DEV Community

ProxyMaster
ProxyMaster

Posted on

Scraping Single-Page Apps by Finding Their Hidden JSON API

WinGate private IPv4 and SOCKS5 proxies, free 2 hour test

You open the page, the data is right there in the browser, but your scraper gets back an almost empty HTML shell. Welcome to the single-page app, where the content you see is rendered by JavaScript after the initial load, usually from a JSON API the page calls in the background. Scraping these does not have to mean spinning up a headless browser for everything. Often there is a much cheaper path, and either way proxies matter more here, not less.

Two ways to scrape an SPA

There are two strategies, and picking the right one saves enormous effort.

  • Hit the JSON API directly. Open the network tab, watch which requests fetch the data, and call those endpoints yourself. You get clean structured JSON, no HTML parsing, and a fraction of the bandwidth. This is almost always the better path when it is available.
  • Render with a headless browser. When the data is obfuscated, protected, or stitched together client-side in a way you cannot easily replicate, use Playwright or Puppeteer to run the JavaScript and read the result. Heavier, but sometimes necessary.

Start by looking for the API. Most of the time it is right there in the network panel, and calling it directly is faster and more reliable than driving a browser.

Calling the hidden API

Once you find the endpoint, replicate the request. Copy the headers the app sends, especially any that identify the client, and call it like any other API.

import requests

headers = {
    "Accept": "application/json",
    "User-Agent": "Mozilla/5.0 ...",
    "Referer": "https://example.com/",
}
proxies = {"http": PROXY, "https": PROXY}
r = requests.get("https://example.com/api/v2/items?page=1",
                 headers=headers, proxies=proxies, timeout=20)
data = r.json()
Enter fullscreen mode Exit fullscreen mode

The catch is that these APIs are often more aggressively rate limited than the pages, because the site knows scrapers target them. That is exactly why proxies matter more here.

Why SPAs make proxies more important

An SPA-backed API is a concentrated target. You are hitting one endpoint repeatedly, in a predictable pattern, and the responses are cheap for the server to count. A single address doing that stands out fast and gets throttled or blocked. Spreading the calls across a rotating pool keeps each address under the endpoint's limit, so the concentrated pattern does not pile up on one origin. If you go the headless route instead, the browser generates a burst of asset requests per page, which also gets one address flagged quickly. Either strategy leans on rotation.

Where the pool comes in

Whether you call the JSON API or render with a browser, the address pool decides whether it holds. WinGate provides private IPv4 proxies with SOCKS5 and automatic rotation from a worldmix pool, so a concentrated API scrape spreads across fresh exits instead of hammering one. The addresses are private rather than shared, traffic is unlimited so a large paginated pull does not meter you, and it supports up to 5000 threads for the rotating pool to feed a fast crawl. It speaks HTTP, HTTPS, and SOCKS5, so the requests client and a headless browser both connect the same way. There is a free 2 hour test, so find the API, point it through the pool, and watch the block rate before you commit.

An honest note: hitting a site's internal API is convenient, but it is still that site's data on that site's terms. Read them, respect rate limits, and do not treat an undocumented endpoint as a license to hammer it. Rotation lets you collect at a sane pace, not abuse an endpoint.

The takeaway: look for the JSON API before reaching for a headless browser, replicate its headers, and route the concentrated request pattern through a rotating pool so one address does not carry it all. Do that and single-page apps stop being the wall your scraper hits and become the easiest data you pull.

Top comments (0)