Scraping Tools
November 2, 2026
5 min

VBA Web Scraping in Excel: A 2026 Step-by-Step Guide

Alex Sadovskij
Alex Sadovskij
CEO Proxy-Cheap
VBA Web Scraping in Excel: A 2026 Step-by-Step Guide
Tóm tắt
Learn how to scrape web data into Excel with VBA, using WinHttpRequest for static pages and SeleniumBasic with Microsoft Edge for JavaScript-heavy ones. Includes ready-to-use macros, proxy setup, and tips to keep your scraper reliable.
  • VBA web scraping runs inside Excel through the Visual Basic Editor, so the basic method needs nothing extra installed.
  • Use WinHttpRequest for static pages (fast, no browser) and SeleniumBasic with Microsoft Edge for pages that render content with JavaScript.
  • Microsoft retired the Internet Explorer 11 desktop app in 2022 and disabled it on most Windows 10 versions in 2023, so the old InternetExplorer automation object is a poor choice for new projects.
  • WinHttpRequest sets a proxy per request with SetProxy and SetCredentials, which is how you route an Excel scraper through a residential or datacenter proxy. The everyday MSXML2.XMLHTTP object has no such setting.

VBA web scraping uses Excel's built-in Visual Basic for Applications to pull data from web pages straight into a spreadsheet. For static pages, a WinHttp.WinHttpRequest.5.1 call fetches the HTML with nothing extra to install. For pages that load content with JavaScript, SeleniumBasic drives Microsoft Edge. The classic Internet Explorer automation object is no longer supported, so this guide uses the current methods.

Did an old macro suddenly stop working? Many Excel scrapers were built on Internet Explorer, and they broke once Windows turned that browser off. The fix is simpler than it sounds.

What is VBA web scraping?

VBA web scraping is the use of Excel's Visual Basic for Applications to request a web page and write the values it returns into worksheet cells. A short macro fetches the page over HTTP, reads the parts you name, and fills the rows. It suits small, spreadsheet-bound jobs where installing other software is not an option.

VBA comes with desktop Office for Windows, so the results land right where you need them. No export, no copy and paste. There are two ways to do it: send a plain HTTP request and read the HTML, or open a real browser and read the page once it finishes loading.

Choose your method: fetch first, render only if needed

Pick the method before writing code. First, check whether the value is already in the page's raw HTML: open the page and search the source for it. If it is there, a WinHttpRequest fetch is enough and it is fast. If the value only appears after JavaScript runs, or the task needs a login or button clicks, use SeleniumBasic with Microsoft Edge. If the job is scheduled or large, it has outgrown Excel.

In Edge, press Ctrl+U to view the page source, then press Ctrl+F and search for a value you can see on screen, such as a price. That one search decides most of what follows.

Work through three questions in order:

  1. Is the data in the raw HTML? Use WinHttpRequest. It's the fastest option and needs nothing beyond Windows and Office.
  2. Does it need JavaScript, a login, or clicks? Use SeleniumBasic driving Microsoft Edge.
  3. Is it scheduled or large? Use a different tool. Excel works best for jobs you run by hand.

The old InternetExplorer.Application object is not a recommended target for new work. Microsoft has retired the browser behind it on current Windows 10 and 11 versions, so rewrite any macro that depends on it. Planning to use a proxy too? Read up on the different proxy types first, since the choice shapes the code later.

Set up Excel for VBA web scraping

1. Turn on the Developer tab. Go to File > Options > Customize Ribbon, tick Developer in the right-hand list, and click OK.

2. Open the Visual Basic Editor. Press Alt+F11, then choose Insert > Module. Your code goes in this blank module.

3. Add the references. In the editor, open Tools > References and tick these two:

  • Microsoft WinHTTP Services, version 5.1 (for sending requests)
  • Microsoft HTML Object Library (for reading the HTML)

4. Save as a macro-enabled workbook. Choose File > Save As and pick Excel Macro-Enabled Workbook (*.xlsm). A regular .xlsx file drops your code when it saves.

Both references ship with Windows and Office, which matters if your IT team doesn't allow extra software. If macros won't run at all, check File > Options > Trust Center.

Scrape a static page with WinHttpRequest (a VBA web scraping example)

For a static page, create a WinHttp.WinHttpRequest.5.1 object, open a GET request, then read responseText once you send it. Load that HTML into a Microsoft HTML Object Library document, select elements with getElementsByClassName or querySelectorAll, and write each value to a cell. It runs fast, since there's no browser to load, and it installs nothing beyond references already in Windows.

This example pulls every quote and author from quotes.toscrape.com, a public practice site built for scraping tutorials.

vba Sub ScrapeStatic()    Dim http As New WinHttp.WinHttpRequest    Dim htmlDoc As New MSHTML.HTMLDocument    Dim quotes As Object, authors As Object    Dim i As Long    http.Open "GET", "https://quotes.toscrape.com/", False    http.Send    If http.Status <> 200 Then        MsgBox "Request failed with status " & http.Status        Exit Sub    End If    htmlDoc.body.innerHTML = http.ResponseText    Set quotes = htmlDoc.getElementsByClassName("text")    Set authors = htmlDoc.getElementsByClassName("author")    With Sheets(1)        .Cells(1, 1).Value = "Quote"        .Cells(1, 2).Value = "Author"        For i = 0 To quotes.Length - 1            .Cells(i + 2, 1).Value = quotes(i).innerText            .Cells(i + 2, 2).Value = authors(i).innerText        Next i    End With End Sub

What each part does:

  • Dim http As New WinHttp.WinHttpRequest creates the request object. It's the same object as CreateObject("WinHttp.WinHttpRequest.5.1"), with autocomplete in the editor.
  • http.Open and http.Send prepare and send a GET request. False makes the macro wait for the answer. Afterwards, http.Status holds the HTTP code (200 means success) and http.ResponseText holds the HTML.
  • htmlDoc.body.innerHTML = ... loads that HTML into a document you can search.
  • getElementsByClassName("text") returns every element with that class. The list starts at 0, so the loop runs to Length - 1.

The Microsoft WinHttpRequest reference lists Open, Send, SetProxy, and SetCredentials as native methods of the object. That's why it's the default choice. It runs without a window and works fine on locked-down machines. Teams use the same pattern for many data collection use cases, from supplier price lists to SEO data collection like title tags.

Keep in mind that this document is a static snapshot where no scripts run. If the site loads its data from a JSON endpoint (check the Network tab in Edge's developer tools), request that URL instead. A few InStr and Split calls go a long way on small JSON responses.

Scrape a dynamic page with SeleniumBasic and Microsoft Edge

When the values load after JavaScript runs, or the task needs a login and clicks, drive a real browser. Install SeleniumBasic, add the Selenium Type Library reference, and match Edge WebDriver to your Edge version. From VBA, Selenium then drives Microsoft Edge to sign in and read content that the plain HTTP fetch cannot see.

  1. Check .NET Framework 3.5. SeleniumBasic needs it. Turn it on under Windows Features if it's missing.
  2. Install SeleniumBasic 2.0.9.0 from the project's GitHub releases page. It's the latest release (2016) and installs to C:\Users\<you>\AppData\Local\SeleniumBasic by default.
  3. Match the driver to your browser. Find your Edge version at edge://settings/help, then download the Microsoft Edge WebDriver with the same version number.
  4. Swap the driver in. Rename msedgedriver.exe to edgedriver.exe and copy it into the SeleniumBasic folder, replacing the old file. Repeat this step whenever Edge updates.
  5. Add the reference. In the Visual Basic Editor, tick Selenium Type Library under Tools > References.

The JavaScript version of the practice site, quotes.toscrape.com/js/, builds its quotes in the browser. The fetch method would come back empty there, so it makes a good test.

vba Sub ScrapeDynamic()    Dim bot As New Selenium.EdgeDriver    Dim el As Selenium.WebElement    Dim r As Long    bot.Start    bot.Get "https://quotes.toscrape.com/js/"    r = 1    For Each el In bot.FindElementsByCss("div.quote span.text")        Sheets(1).Cells(r, 3).Value = el.Text        r = r + 1    Next el    bot.Quit End Sub

bot.Start opens Edge, and bot.Get loads the page and waits for it. FindElementsByCss returns every match, while FindElementByCss returns only the first. el.Text reads what the browser shows, and bot.Quit closes Edge.

Pick this over the fetch for logins and for values that only show up once scripts run. A real browser loads every asset on the page, so each page takes longer than a plain request. Keep SeleniumBasic for the pages that need it and use the fetch everywhere else.

SeleniumBasic also has a ChromeDriver class that works the same way. If you check pages by hand in Chrome before writing a macro, our Chrome proxy extension makes switching proxies quick.

Route your VBA scraper through a proxy

WinHttpRequest is the most direct native VBA object for setting a proxy per request. Call SetProxy on the client, call Open, then pass the gateway credentials with SetCredentials using the proxy flag, and send. Because SetCredentials only works after Open, repeat it after every Open when you reuse the same client for a list of pages. MSXML2.XMLHTTP has no per-request proxy setting, so use WinHttpRequest when a proxy is involved.

Many sites show different prices or search results depending on the visitor's location. A proxy in the right country gives you location-accurate results for price monitoring and localization checks on publicly available data.

How the common native objects compare:

Native VBA objectPer-request proxyProxy credentialsUse it for
WinHttp.WinHttpRequest.5.1Yes (SetProxy)Yes (SetCredentials, proxy flag)Any request that needs an explicit proxy
MSXML2.ServerXMLHTTP.6.0Yes (setProxy)Yes (setProxyCredentials)Existing code already built on MSXML
MSXML2.XMLHTTPNo usable control (uses the Windows proxy settings)NoSimple calls with no proxy requirement

The working pattern:

vba Sub ScrapeViaProxy()    Dim http As New WinHttp.WinHttpRequest    ' 2 = use the proxy named here (host:port from your dashboard)    http.SetProxy 2, "your-proxy-host:port"    http.Open "GET", "https://api.ipify.org/", False    ' 1 = these credentials are for the proxy; call this after Open    http.SetCredentials "proxy-username", "proxy-password", 1    http.Send    Debug.Print http.Status, http.ResponseText End Sub

In the Microsoft SetProxy reference, setting 2 applies the proxy to this object only, and SetProxy has to run before Send. The Microsoft SetCredentials reference explains that flag 1 sends the credentials to the proxy and that the method returns an error if Open hasn't been called yet. The test URL returns the IP address the site sees, so the Immediate window (Ctrl+G) should show the proxy's IP, not yours.

Your host, port, username, and password are in your Proxy-Cheap dashboard. Here's how to find your proxy host and port if you're unsure.

Match the proxy type to the job:

  • Rotating residential proxies give you geo-specific, location-accurate results on public pages, with country and city targeting. They're billed pay-as-you-go per GB.
  • Static residential proxies, also called static residential (ISP), keep one IP for the length of your plan. That suits consistent sessions and logins.
  • Datacenter proxies deliver high throughput for public, unprotected pages, with unlimited bandwidth on datacenter IPv4 and IPv6 plans.
  • ISP proxies come in static and rotating options.

Proxy-Cheap plans come with no monthly commitment, and you can cancel anytime. Check the live product pages for current pricing.

Keep your Excel scraper reliable

VBA is single-threaded, so a synchronous request freezes Excel until it returns. Keep each run responsive: pace requests (roughly one per second), write results to the sheet as they arrive, and add a status column so a stopped run resumes from where it left off. Small batches with checkpoints turn a run people cancel into one that finishes.

The easiest pattern is a queue sheet. Put URLs in column A and let the macro write "done" or "error" in column B, so the next run skips finished rows.

vba Function FetchPage(http As WinHttp.WinHttpRequest, url As String) As Boolean    On Error GoTo Failed    http.Open "GET", url, False    http.Send    FetchPage = (http.Status = 200)    Exit Function Failed:    FetchPage = False End Function Sub ScrapeQueue()    Dim http As New WinHttp.WinHttpRequest    Dim ws As Worksheet, r As Long, ok As Boolean    Set ws = ThisWorkbook.Sheets("Queue")    For r = 2 To ws.Cells(ws.Rows.Count, 1).End(xlUp).Row        If ws.Cells(r, 2).Value <> "done" Then            ok = FetchPage(http, ws.Cells(r, 1).Value)            If Not ok Then ok = FetchPage(http, ws.Cells(r, 1).Value) ' retry once            If ok Then                ws.Cells(r, 3).Value = Len(http.ResponseText) ' swap in your own parsing                ws.Cells(r, 2).Value = "done"            Else                ws.Cells(r, 2).Value = "error"            End If            DoEvents            Application.Wait Now + TimeValue("0:00:01")        End If    Next r End Sub

DoEvents lets Excel redraw between pages, and the one-second wait keeps request rates modest. The same queue works for checking landing pages in ad verification workflows.

When VBA is the right tool, and when to move on

VBA scraping suits small, spreadsheet-bound jobs on machines where extra software cannot be added. Once a job runs on a schedule, grows large, or needs heavy rendering, a small script in a language your team already uses is easier to maintain, and it can still write to the same workbook.

VBA is a great fit when the results belong in a spreadsheet anyway, you're pulling tens or hundreds of pages, and you can't install other tools on your work machine. It's time to move on when the job needs to run unattended or covers thousands of pages. At that point, a script that calls a proxy API or runs on a server will scale better for ongoing market research.

If your source is a clean HTML table, try Power Query first. Data > Get Data > From Web imports tables with no code.

Pros and cons of VBA web scraping

ProsCons
Built into Office for Windows, so there's nothing new to buyTied to Windows and desktop Excel
The HTTP method needs no installsSingle-threaded, so large jobs take a while
Results land directly in cellsBrowser automation needs SeleniumBasic and a matching driver
Easy to learn for spreadsheet usersBest paired with a proxy for location-accurate public data

For a recurring task like price monitoring on a few dozen product pages, the pros usually win.

Proxy-Cheap puts rotating residential, static residential (ISP), datacenter IPv4, and mobile proxies under one account, so you can start small and switch types as your Excel workflows grow.

Câu hỏi thường gặp

Microsoft ended support for the Internet Explorer 11 desktop app on June 15, 2022, and disabled it through a Microsoft Edge update on February 14, 2023, according to Microsoft's IE11 end-of-support announcement. Macros built on the InternetExplorer.Application object depended on that app, so rebuild them with WinHttpRequest for static pages or SeleniumBasic with Microsoft Edge for dynamic ones.

Yes, for static pages. WinHttp.WinHttpRequest.5.1 and the Microsoft HTML Object Library ship with Windows and Office, so a fetch-and-parse macro needs no third-party install. Dynamic pages need SeleniumBasic, which does require an install.

Both send HTTP requests from VBA, but they differ on proxy control. WinHttpRequest exposes SetProxy and SetCredentials, while MSXML2.XMLHTTP follows the Windows proxy settings and has no per-request option, so use WinHttpRequest when a proxy is involved.

Yes. Add bot.AddArgument "--proxy-server=host:port" before bot.Start, and Edge sends its traffic through that proxy. This method doesn't pass a username and password, so use a proxy with IP whitelist authentication, which Proxy-Cheap supports on its static residential and datacenter lines.

Plain HTTP requests only see the raw HTML, so values added by JavaScript will be missing. For those pages, drive Microsoft Edge with SeleniumBasic, which reads the page after it renders.

The HTTP-request and SeleniumBasic methods rely on Windows components, so they do not carry over to Excel for Mac. On a Mac, a small script in a cross-platform language is the more reliable route.

VBA runs on one thread, so a synchronous request pauses Excel until it returns. Add DoEvents inside your loop and process URLs in small batches so the workbook stays responsive.

Collecting publicly available data is generally acceptable, but the site's terms of service and applicable law still apply. Review them before you run a job, and keep request rates modest. This is general guidance, not legal advice.