A practical 2026 engineer's guide to scrape websites without getting blocked: proxies, rate limits, TLS fingerprints, Playwright stealth, Cloudflare and silent-block monitoring.
Every week I get asked some version of the same question: how do I scrape websites without getting blocked? After years of building production scrapers for US and European clients, my honest answer is that there is no single trick. Staying unblocked is the sum of many small decisions: how fast you request, what your traffic looks like on the wire, how your browser fingerprints, and whether you notice the moment a site quietly starts feeding you garbage. This guide walks through what actually matters in 2026.
Why sites block you in the first place
Anti-bot systems group their signals into three buckets, and you need to defeat all three. The first is rate: too many requests from one IP in too short a window. The second is fingerprint: your IP reputation, TLS handshake, HTTP header order, and browser properties combined into a score. The third is behavior: do you move like a human, or do you hit ten product pages per second with no mouse movement and no referrer?
Most beginners only fix rate. They add a proxy, slow down, and still get blocked, because their fingerprint screams "Python script" on the very first request. Treat all three as a system.
Respect robots.txt, ToS, and the law
Before any technique, decide whether you should be scraping at all. Read robots.txt and the Terms of Service. Public, non-personal data is generally lower risk; data behind a login or personal data carries real legal weight under GDPR and similar regimes. I am an engineer, not your lawyer, but the rule I live by is simple: scrape public data politely, never hammer infrastructure you do not own, and never collect personal data you cannot justify. Being a good citizen also happens to keep you unblocked longer.
IP rotation: residential vs datacenter proxies
Your IP is the loudest signal. A single datacenter IP making thousands of requests is the easiest thing in the world to block. Rotating proxies spread your traffic across many addresses so no single one looks abusive. The type you choose is a cost-versus-stealth tradeoff.
| Proxy type | Stealth | Cost | Best for |
|---|---|---|---|
| Datacenter | Low | Cheap | Lenient sites, internal APIs, high volume |
| ISP / static residential | Medium-high | Medium | Sessions that must persist on a stable IP |
| Residential (rotating) | High | Expensive | Sites with strong IP reputation checks |
| Mobile (4G/5G) | Very high | Most expensive | Aggressive anti-bot, social platforms |
Start with datacenter proxies and only escalate to residential or mobile when you measure blocks. Paying for mobile proxies on a site that never checks IP reputation is just burning money.
Throttling and concurrency
Even with perfect proxies, an unnatural request rate gives you away. I cap concurrency per domain, add randomized delays, and use exponential backoff on errors. The goal is to look like a handful of curious humans, not a stampede.
import asyncio, random
import httpx
SEM = asyncio.Semaphore(5) # max 5 in flight per domain
async def fetch(client, url):
async with SEM:
await asyncio.sleep(random.uniform(1.0, 3.0))
for attempt in range(4):
r = await client.get(url, timeout=20)
if r.status_code == 429:
await asyncio.sleep(2 ** attempt)
continue
return r
return NoneNotice the explicit handling of 429 Too Many Requests. When a site asks you to slow down, listen. Ignoring 429s is the fastest path to a permanent ban.
Realistic headers and TLS/JA3 fingerprints
A plain requests or httpx call sends headers in an order and with values no real browser ever uses, and its TLS handshake produces a JA3 fingerprint that does not match Chrome or Firefox. Modern anti-bot tools read this on the first packet, before you send a single header you control.
Fixing it means two things. Send a complete, consistent set of headers (User-Agent, Accept, Accept-Language, Sec-CH-UA, Referer) that all describe the same browser. And use a client that mimics a real browser's TLS, such as curl_cffi with impersonate="chrome". Mismatched layers are a dead giveaway: a Chrome User-Agent riding on a Python TLS fingerprint fools no one.
Headless browser detection and Playwright stealth
When a site is JavaScript-heavy or aggressively defended, I reach for a real browser via Playwright. But vanilla headless Chrome leaks: navigator.webdriver is true, the GPU is software-rendered, plugins are empty, and timing is too clean. Stealth patches close these gaps.
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(headless=True, args=[
"--disable-blink-features=AutomationControlled",
])
ctx = browser.new_context(
user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/130.0 Safari/537.36",
locale="en-US", timezone_id="America/New_York",
)
page = ctx.new_page()
page.goto("https://example.com", wait_until="networkidle")Use a maintained stealth plugin rather than hand-patching everything, and make sure your timezone, locale, and proxy geolocation all agree. A residential IP in Texas paired with a browser set to Tel Aviv time is a contradiction that defeats the whole exercise.
Cloudflare, DataDome, and hCaptcha
These are the heavyweights, and there is no honest one-line bypass. At a high level: Cloudflare and DataDome score every request on IP reputation, TLS fingerprint, and behavior, then serve a managed challenge when suspicious. hCaptcha and Turnstile add an interactive puzzle. Your realistic options are a high-quality stealth browser on residential or mobile proxies, a commercial unblocking service or CAPTCHA-solving provider, or simply slowing down enough to stay under the suspicion threshold. Whether building your own bypass is worth it is exactly the kind of question I cover in build versus buy a web scraper, because for defended targets a managed service is often cheaper than the engineering time.
Session and cookie management
Many sites set a clearance cookie after the first successful load. Throwing it away and re-solving the challenge on every request wastes proxy bandwidth and looks robotic. Persist cookies per session, keep each session pinned to one IP, and let it age naturally. A session that logs in, browses, and keeps its cookies for an hour reads far more human than a thousand cold first-time visits.
When to use an API instead
The cleanest way to scrape websites without getting blocked is often not to scrape at all. Check for an official API, a mobile app endpoint, an RSS feed, or a public dataset before writing a single selector. An API is faster, more stable, and explicitly permitted. I only fall back to browser scraping when no structured source exists.
Monitoring for silent blocks
The dangerous failure is not the 403. It is the silent block: the site returns 200 OK with empty results, stale prices, or subtly poisoned data to waste your time. Without monitoring you will not notice for days. I assert on expected fields and counts, alert when extraction rates drop, log status codes and response sizes, and periodically diff against a known-good baseline. Catching a silent block early is what separates a reliable pipeline from a quietly broken one, which is why I treat validation as a core part of any data pipeline for scraped data.
Conclusion
There is no magic flag that makes blocks disappear. You stay unblocked by layering good habits: rotate IPs appropriately, throttle politely, match your headers and TLS, harden your browser, manage sessions, prefer APIs, and monitor relentlessly for silent failures. Get those right and most sites will never notice you.
If you need a resilient scraper that keeps delivering clean data without getting blocked, book a call and tell me about your target, or reach out through the contact form.
Frequently asked questions
Is web scraping legal?
Scraping publicly available, non-personal data is generally lower risk, but it always depends on the site's Terms of Service and your jurisdiction. Data behind a login or personal data falls under regimes like GDPR and carries real legal weight. I am an engineer, not a lawyer, so for anything sensitive get proper legal advice.
Do I always need residential proxies?
No. Start with cheaper datacenter proxies and only escalate to residential or mobile when you actually measure blocks. Paying for residential traffic on a site that never checks IP reputation is wasted money. Match the proxy tier to the target's defenses.
Why do I get blocked even with proxies?
Because proxies only fix the IP signal. If your TLS/JA3 fingerprint, header order, or headless browser properties still look automated, you get scored as a bot on the first request regardless of which IP you use. You have to address rate, fingerprint, and behavior together.
How do I detect a silent block?
A silent block returns 200 OK but with empty, stale, or poisoned data. Catch it by asserting on expected fields and record counts, alerting when extraction rates drop, logging response sizes, and periodically diffing results against a known-good baseline.
Keep reading
Related service
Web Scraping
Reliable web scraping and data pipelines that deliver clean data.
About the author
Yehonatan Saadia
Freelance automation, web & MVP engineer
I'm Yehonatan Saadia, a senior engineer who builds business automation, custom websites, and MVPs for small and mid-sized companies across the US, Europe, and Israel. These guides come from real client work, not theory.
Work with meHave a project like this?
Tell me what you're trying to automate or build and I'll tell you the fastest reliable way to ship it.
