Skip to content

The Proxy Playbook · Chapter 10

Staying Unblocked

How websites decide a visitor is automated, how a block really shows up, and a cheapest-first order for fixing it.

  • The seven layers a website checks
  • Hard blocks and soft blocks
  • Symptom, cause and fix table
  • An escalation ladder by cost

7 min read · page 65 of the PDF

A price scraper runs clean for three weeks. On a Monday every request still returns 200, and every price field in the output is empty. Nothing failed loudly. The site stopped trusting the visitor and began serving a page without the data.

What a website checks

Bot detection is a stack of separate checks, and a request has to pass every one a site runs. Some happen before the server reads a single header. Others build up over days of account activity.

1 · IP reputationNetwork type, past abuse, and how many clients share the range.
2 · Request rate and patternRequests per IP and per session, URL order, clockwork timing.
3 · TLS and HTTP/2 fingerprintThe handshake reveals the client library behind the request.
4 · HeadersUser-Agent, Accept-Language, header order, anything a browser would send.
5 · Browser and JavaScript fingerprintCanvas, WebGL, fonts, and automation flags such as navigator.webdriver.
6 · BehaviorMouse movement, scrolling, time on page, the path through the site.
7 · Account-level signalsAccount age, login history, linked devices, activity that repeats across accounts.
The layers a website can check, from the network up to the account.

A proxy changes layer 1 and helps with layer 2 by spreading requests across addresses. It does nothing for the other five. That explains a familiar complaint: premium residential IPs that still get blocked on the first request.

A proxy changes the IP address and nothing else about the request.

Layer 3 catches many scripts. Python's requests library opens a TLS connection that looks nothing like Chrome's. If the User-Agent header then claims to be Chrome, the two layers disagree, and that mismatch is easy to flag. Detection vendors hash the handshake into fingerprints with names such as JA3 and JA4. HTTP/2 settings and header order give a second fingerprint of the same kind.

Layers 5 and 6 only apply when the site runs JavaScript checks, which a plain HTTP client never executes. On those sites the missing script result is itself the signal. Layer 7 matters for anything logged in, and it is where the profile hygiene from Chapter 9 pays off.

How a block actually shows up

Blocks rarely announce themselves. A scraper that only counts 403s will miss most of the forms below.

403 Forbidden

A flat refusal. On the first request it usually points at the IP range or the client fingerprint.

429 Too Many Requests

A rate limit. It often carries a Retry-After header that says how long to wait.

CAPTCHA or challenge page

A puzzle or a "checking the browser" screen. It can arrive with a 200, 403 or 503 status.

Redirect

A 302 to a login page, a consent wall, the home page or another country's store.

Soft block

A 200 with wrong or missing data: empty result lists, blank prices, stale pages, fewer items than a real visitor sees.

Silence

Timeouts and reset connections. The server drops the request without an answer.

Soft blocks do the most damage because the pipeline keeps running and bad data flows into reports. Chapter 6 made the point for billing: a 200 is not a success. The same check belongs in the code. Every response should be tested for something a good page always contains, such as a product title or a price element.

python · requests
import requests

PROXY = "http://USERNAME:[email protected]:7000"
MARKERS = ("captcha", "unusual traffic", "access denied")

def classify(r):
    body = r.text.lower()
    if r.status_code in (403, 429):
        return "blocked"
    if r.history and "login" in r.url:
        return "redirected"
    if any(m in body for m in MARKERS):
        return "challenge"
    if 'class="price"' not in body:
        return "soft-block"
    return "ok"

r = requests.get("https://example.com/item/42",
                 proxies={"http": PROXY, "https": PROXY}, timeout=30)
print(r.status_code, len(r.content), classify(r))

The marker strings and the price selector are placeholders. Each target needs its own, taken from a real good page and a real blocked page. Log the label with every request so that success rate means valid data.

Symptom, likely cause, first fix

Most blocks fall into a small set of patterns. Chapter 8 covered errors from the proxy side. This table covers what the target sends back.

SymptomLikely causeFirst fix
403 on the very first requestFlagged IP range or TLS mismatchUse a browser-like client, then another IP type
403 after a few dozen pagesRate or pattern rule trippedLower concurrency and rotate per session
429Too many requests per IP or sessionBack off, honor Retry-After, widen the pool
CAPTCHA on every pageLow IP trust or automation flagsResidential or mobile IP, real browser
Redirect to loginLost cookies, or content needs an accountKeep cookies on a sticky session
200 with empty or odd dataSoft block or wrong exit countryValidate content and check geo-targeting
Timeouts and resetsDead exit node or silent dropRetry on a new IP with a timeout
407Proxy credentials or allowlistFix at the provider; the site never saw it
Common block symptoms with the cause to suspect first.

When the cause is unclear, separate the IP from the client. Load the target in a normal browser through the same proxy, then compare. The Proxy Checker also shows whether an address is registered as datacenter, residential or mobile.

The escalation ladder

Chapter 5 gave a ladder of proxy types. This one is wider, because the IP is only one of the things that can be changed. Fixes have very different prices. Slowing down is free. Residential traffic runs roughly $1 to $5 per GB at entry level. Datacenter traffic runs roughly $0.10 to $1.40. Live figures are on the pricing page. A headless browser multiplies both bandwidth and compute. Climb one rung at a time, rerun the same URL sample, and stop at the first rung that works.

1. Slow downFree

Cut concurrency, add random delays, keep cookies, and retry with backoff.

2. Fix the clientEngineering time

Send a full, consistent header set and use a client with a browser-like TLS handshake.

3. Upgrade the IPHigher price per GB

Climb the proxy-type ladder from Chapter 5: datacenter, ISP, residential, mobile.

4. Run a real browserMore bandwidth and compute

Render the page in Playwright or Puppeteer so JavaScript checks get real answers.

5. Hand it offPer-request pricing

Send the URL to a scraper API or unblocker and pay for successful results.

An escalation ladder. The meter shows relative cost per page, not a measured figure.

For rung 2, open-source clients such as curl_cffi copy a real browser's TLS and HTTP/2 handshake. They stay as light as a plain HTTP library. On sites that run no JavaScript checks, that one change can remove the need for rungs 3 and 4.

The order of rungs 3 and 4 can swap. A target that needs JavaScript to show any content needs a browser whatever the IP. For the IP rung, the web scraping page in the directory lists providers for that job.

When a scraper API or unblocker makes sense

A scraper API or unblocker takes a URL and returns the page. The vendor picks the IP, sets the fingerprint, renders JavaScript where needed and retries on failure. These products are priced per successful request or per monthly plan. Where billing is per success, failed attempts are the vendor's cost.

If…Then…
The target stays blocked after rungs 1 to 4Buy the unblocker and stop spending engineering time
The team is small and the data is the productA scraper API removes proxy and browser maintenance
The target is easy and volume is highRaw datacenter proxies will usually cost far less
The job needs a logged-in session or multi-step flowsKeep control with proxies and a real browser
Choosing between raw proxies and a managed unblocker.

Many teams end up with both: raw proxies for the easy majority of targets and an unblocker for the stubborn few. The proxy API providers page lists vendors that sell this kind of product. ProxyLook's companion book, Scraping Without Blocks, goes deeper on each detection layer.

No setup is permanent

Detection systems change without notice. A configuration that returned clean data last month can start failing this week, and no proxy type, browser or vendor is immune to that. Mobile IPs get challenged. Unblockers return errors on hard targets.

The practical answer is monitoring. Track the share of valid pages per target every day and alert on a drop. Keep the fixed URL sample ready for a quick diagnosis. The next chapter turns those numbers into a cost model.

Key takeaways

  • Websites can check seven layers, and a proxy only changes the first one.
  • A TLS handshake that disagrees with the User-Agent can get a script blocked on its first request.
  • Soft blocks return a 200 with wrong data, so validate page content on every response.
  • Escalate from free fixes to expensive ones, one rung at a time, against a fixed URL sample.
  • A scraper API or unblocker suits hard targets and small teams, while raw proxies stay cheaper for easy ones.
  • No proxy, browser or vendor makes a scraper immune to blocks, so monitor valid-data rate daily.

Prefer the designed PDF? The Proxy Playbook is 91 pages, free, with no sign-up.

Download the PDF