How to Avoid Getting Blocked While Scraping

Updated June 2026
Web scrapers get blocked when their request patterns look automated to the target server. Avoiding blocks requires a combination of proxy rotation, realistic request headers, human-like timing, and careful handling of anti-bot systems like Cloudflare and DataDome. This guide covers every layer of the anti-detection stack and gives you a practical framework for scraping reliably at scale.

Why Web Scrapers Get Blocked

Websites block scrapers for several practical reasons. Automated traffic consumes server resources without generating ad revenue or sales conversions. Competitors use scraping to steal pricing data, product listings, and content. Credential-stuffing bots and spam harvesters exploit the same HTTP pathways that scrapers use, so anti-bot systems often treat all automated traffic as a potential threat.

The core problem is that most scraping scripts behave nothing like a real browser. They send requests at machine speed, ignore cookies and JavaScript, use the same IP address for thousands of requests, and present minimal or incorrect HTTP headers. Each of these signals, on its own, raises suspicion. Combined, they make automated traffic trivially easy to identify.

Understanding what triggers blocks is the first step toward avoiding them. The most common causes include sending too many requests per second from a single IP, using a known datacenter IP range, presenting a User-Agent string that does not match any real browser, failing to execute JavaScript on pages that require it, ignoring Set-Cookie headers, and requesting pages in patterns that no human visitor would follow. Every blocked request wastes time, so getting the fundamentals right from the beginning saves hours of debugging later.

Blocking is not always binary. Many sites use progressive enforcement: the first sign of automated behavior triggers a CAPTCHA, repeated violations lead to temporary IP bans, and persistent offenders get permanently blacklisted at the IP or fingerprint level. Some sites silently serve altered data to suspected bots, returning incorrect prices, outdated inventory counts, or randomized content that pollutes your dataset without any obvious error message.

The Anti-Bot Detection Stack

Modern anti-bot systems operate at multiple layers simultaneously. Understanding this stack helps you identify which layer is catching your scraper and apply the right countermeasure.

Network layer: The most basic check examines your IP address. Is it from a known datacenter range (AWS, Google Cloud, DigitalOcean) or a residential ISP? Datacenter IPs are flagged immediately by most commercial anti-bot services because legitimate users almost never browse from EC2 instances. IP reputation databases maintained by companies like MaxMind, IPQualityScore, and Spur track IP addresses associated with previous abuse.

HTTP layer: Servers inspect request headers for inconsistencies. A real Chrome browser sends a specific set of headers in a specific order: Host, Connection, sec-ch-ua, sec-ch-ua-mobile, sec-ch-ua-platform, Upgrade-Insecure-Requests, User-Agent, Accept, Sec-Fetch-Site, Sec-Fetch-Mode, Sec-Fetch-User, Sec-Fetch-Dest, Accept-Encoding, Accept-Language. Python's requests library, by default, sends a completely different set in a different order. This mismatch is a clear signal.

TLS layer: Every TLS client (browser, HTTP library, curl) produces a unique fingerprint during the TLS handshake. The JA3 and JA4 fingerprinting methods hash the cipher suites, extensions, and elliptic curves that a client advertises. If your request claims to be Chrome 126 via the User-Agent header but presents a JA3 hash that matches Python's urllib3, the server knows you are lying. Libraries like curl-impersonate and tls-client exist specifically to solve this problem by mimicking real browser TLS fingerprints.

JavaScript layer: Anti-bot services like Cloudflare Turnstile, DataDome, and PerimeterX inject JavaScript challenges that collect dozens of browser signals: canvas fingerprint, WebGL renderer, installed fonts, screen resolution, timezone, language, the presence of navigator.webdriver, the behavior of certain DOM APIs, and timing patterns of mouse movements and keystrokes. Simple HTTP scrapers fail these challenges completely because they never execute JavaScript.

Behavioral layer: The most sophisticated systems analyze browsing patterns over time. Real users scroll, click, hover, pause to read, and navigate between pages in organic patterns. Bots tend to request pages in sequential order, never load images or CSS, complete forms instantly, and access pages at perfectly regular intervals. Behavioral analysis catches scrapers that pass every other check by looking at the overall session pattern.

IP Management and Proxy Rotation

IP rotation is the most fundamental anti-blocking technique. If each request comes from a different IP address, rate limiting per IP becomes ineffective, and permanent IP bans only block addresses you were going to discard anyway.

Datacenter proxies are the cheapest option, typically costing a few dollars per hundred IPs per month. They are fast and reliable, but their IP ranges are well-known and many sites block them outright. Datacenter proxies work well for sites with minimal anti-bot protection, like small business sites, public government databases, and academic repositories.

Residential proxies route traffic through real consumer ISP connections, making requests appear to come from normal households. They cost significantly more (typically billed per gigabyte of data transferred), but they pass IP reputation checks that datacenter proxies fail. Major providers include Bright Data, Oxylabs, SOAX, and Smartproxy. Residential proxies are essential for scraping sites protected by Cloudflare, DataDome, or similar services.

ISP proxies (also called static residential) combine the reliability of datacenter hosting with residential IP classification. They are static IPs hosted in datacenter infrastructure but registered under residential ISP ASNs. They cost more than standard datacenter proxies but less per-request than rotating residential proxies, making them ideal for long-running sessions where you need to maintain the same IP without arousing suspicion.

Mobile proxies use 4G and 5G connections from real mobile carriers. Because mobile carriers use CGNAT (Carrier-Grade NAT), thousands of legitimate users share each IP address. This makes mobile IPs extremely difficult to block without causing massive collateral damage to real users. Mobile proxies are the most expensive option but the hardest to detect.

Effective rotation is not just about having many IPs. You need to distribute requests intelligently: assign specific IPs to specific sessions, retire IPs that receive CAPTCHAs or errors, avoid using the same IP for the same domain within a short window, and match IP geolocation to the content you are requesting. A German IP requesting English-language product pages on a US e-commerce site is suspicious, even if the IP itself has a clean reputation.

Request Headers and Browser Fingerprints

Sending the correct HTTP headers is surprisingly important. The User-Agent string gets the most attention, but it is only one of many signals that must be consistent.

A modern Chrome browser on Windows sends roughly 15 to 20 headers with each navigation request. Beyond User-Agent, the sec-ch-ua family of Client Hints headers reveals the browser brand, version, platform, and whether the device is mobile. The Accept header varies by resource type: HTML pages get a different Accept value than images, scripts, or XHR requests. The Sec-Fetch headers (Site, Mode, User, Dest) describe the context of the request, indicating whether it is a top-level navigation, a sub-resource load, or an AJAX call.

Consistency matters more than any individual value. If your User-Agent claims to be Chrome 126 on macOS, your sec-ch-ua-platform should say "macOS", your Accept-Language should include "en-US" (or another appropriate locale), and your TLS fingerprint should match Chrome. A mismatch between any of these signals is a strong indicator of automation.

Header order also matters. Real browsers send headers in a consistent, browser-specific order. Firefox puts Host first, then User-Agent, then Accept. Chrome uses a different order. If your HTTP library sends headers in alphabetical order or in the order you added them to a dictionary, that order itself becomes a fingerprint. Some libraries (like httpx in Python) preserve insertion order, while others sort headers. Using curl-impersonate or a real browser via Playwright or Puppeteer sidesteps this problem entirely because the real browser engine generates correct headers in the correct order.

When rotating User-Agent strings, use only current, popular browser versions. A User-Agent claiming to be Chrome 89 on Windows 7 is immediately suspicious because Chrome 89 was released in 2021 and Windows 7 reached end-of-life in 2020. Use the latest stable versions of Chrome, Firefox, and Safari, and update your rotation list regularly. Avoid exotic or rare User-Agent strings that make your traffic stand out in server logs.

Rate Limiting and Timing Patterns

The speed at which you send requests is the single easiest signal for servers to detect. No human clicks through pages at a rate of 10 requests per second, and no legitimate browsing session makes 50,000 requests in an hour.

A safe starting point for most sites is one request every 2 to 5 seconds. Heavily protected sites may require delays of 10 seconds or more. Sites with minimal protection might tolerate one request per second. The right speed depends on the target site's infrastructure, its anti-bot measures, and how many other scrapers are hitting it simultaneously.

Fixed delays are better than no delays, but they create unnaturally regular timing patterns. Real human browsing has variable timing: quick clicks when scanning a list, longer pauses when reading content, occasional bursts when navigating through pagination. Adding randomized jitter to your delays creates more realistic patterns. Instead of waiting exactly 3 seconds between each request, wait a random interval between 1.5 and 6 seconds, with the distribution weighted toward the shorter end.

Exponential backoff is essential for handling rate limit responses. When you receive a 429 (Too Many Requests) or 503 status code, double your delay before retrying. If you get blocked again, double it again. This prevents your scraper from hammering a server that is already under stress, which would escalate a temporary rate limit into a permanent ban.

Time-of-day patterns also matter. Real website traffic follows predictable curves: low at night, ramping up in the morning, peaking in the afternoon, and tapering off in the evening. A scraper that runs at a constant rate 24 hours a day stands out in traffic analysis. Scheduling your heaviest scraping during peak traffic hours helps your requests blend into the crowd.

For large-scale scraping jobs, distribute requests across multiple domains or sections of a site rather than hitting one endpoint repeatedly. If you need to scrape 100,000 product pages, rotate through product categories rather than requesting pages 1 through 100,000 sequentially. This distributes the load across the target site's infrastructure and makes your traffic pattern look more like organic browsing.

Handling JavaScript-Heavy Sites

An increasing number of websites render content client-side using React, Vue, Angular, or similar frameworks. Fetching the raw HTML with a simple HTTP request returns an empty shell with a JavaScript bundle reference, but none of the actual content. Scraping these sites requires executing JavaScript, which means using a real or headless browser.

Headless browsers like Playwright, Puppeteer, and Selenium drive real browser engines (Chromium, Firefox, WebKit) programmatically. They execute JavaScript, render the DOM, handle cookies and sessions, and produce network traffic that looks identical to a real browser. This makes them the best tool for scraping JavaScript-heavy sites and bypassing anti-bot checks that rely on JavaScript challenges.

However, headless browsers have their own detection vectors. The default configuration of most headless browser frameworks sets navigator.webdriver to true, uses viewport dimensions that differ from common screen sizes, lacks real GPU rendering, and can be detected through a battery of JavaScript API checks. Anti-bot services maintain extensive lists of these signals.

Stealth plugins address many of these issues. Playwright Extra with the stealth plugin patches the most common detection vectors: it sets navigator.webdriver to undefined, spoofs WebGL vendor strings, adds realistic plugin and language arrays, and patches various JavaScript APIs that behave differently in headless mode. Similar plugins exist for Puppeteer. These patches are not foolproof, as anti-bot services continuously update their detection methods, but they significantly raise the difficulty of detecting your headless browser.

Resource consumption is the main drawback of headless browsers. Each browser instance uses 100 to 500 MB of RAM, depending on the page complexity. Spinning up thousands of concurrent browser instances requires substantial infrastructure. To manage resources, reuse browser contexts across multiple pages, block unnecessary resource loads (images, fonts, analytics scripts, ad networks), and close pages promptly after extracting data.

CAPTCHAs and Challenge Pages

When a site suspects automated traffic but is not certain enough to block outright, it typically serves a CAPTCHA or challenge page. Cloudflare Turnstile, Google reCAPTCHA, hCaptcha, and DataDome CAPTCHAs are the most common barriers scrapers encounter.

The first line of defense is to avoid triggering CAPTCHAs in the first place. Proper proxy rotation, realistic headers, appropriate request rates, and stealth-configured headless browsers prevent most CAPTCHA challenges. If you are seeing CAPTCHAs frequently, it usually means one of your other anti-detection measures is failing.

When CAPTCHAs are unavoidable, third-party solving services like 2Captcha, Anti-Captcha, and CapSolver provide APIs that solve CAPTCHAs programmatically. You send the CAPTCHA parameters (site key, page URL, and sometimes the CAPTCHA image) to the service, and it returns a solution token that you submit back to the target site. Solving times range from a few seconds for simple image CAPTCHAs to 30 seconds or more for reCAPTCHA v2.

Cloudflare's challenge pages deserve special attention because they protect a significant portion of the web. Cloudflare uses a multi-layered approach: a JavaScript challenge that checks browser capabilities, followed by Turnstile (their CAPTCHA replacement) if the JavaScript challenge fails. The most reliable way to pass Cloudflare is to use a residential proxy with a stealth-configured headless browser. Tools like cloudscraper and FlareSolverr exist specifically for this purpose, though their effectiveness varies as Cloudflare updates its detection methods.

Challenge cookies are important to preserve. Once you solve a CAPTCHA or pass a JavaScript challenge, the site sets cookies (like Cloudflare's cf_clearance) that grant access for subsequent requests. Saving and reusing these cookies avoids solving the same challenge repeatedly. Store cookies per session and per IP, and discard them when you rotate to a new proxy.

Proper cookie and session handling is often overlooked but plays a significant role in avoiding detection. Real browsers maintain persistent cookie jars, send cookies with every request, respect Set-Cookie headers, and handle cookie domains and paths correctly. Many scraping scripts ignore cookies entirely, which is a clear automation signal.

At minimum, your scraper should accept and resend cookies throughout a browsing session. Use a session object (like requests.Session in Python) that automatically handles cookie persistence. When using headless browsers, cookies are managed by the browser engine itself, but you still need to ensure cookies are preserved across page navigations within the same session.

Session consistency matters. If you rotate proxies mid-session, the server sees the same session cookie arriving from a different IP, which is suspicious. Match proxy IPs to sessions: assign a proxy to a session at the start and keep it for the duration of that session. If you must change IPs, start a new session with fresh cookies.

Authentication cookies require extra care. If your scraping task involves logging into a website, the login session should persist across all requests for that account. Logging in repeatedly from different IPs triggers account security alerts on most sites. Instead, log in once per session, save the authentication cookies, and reuse them until they expire.

Some sites use cookie-based bot detection, planting tracking cookies that record browsing history and flag sessions with unusual navigation patterns. Accepting and storing all cookies, including tracking cookies from analytics and advertising scripts, makes your session look more like a real browsing session.

Ethical Scraping and Legal Compliance

Technical capability does not equal legal permission. Before scraping any website, understand the legal framework that applies to your situation.

The robots.txt file declares which paths a site owner prefers bots not to access. While robots.txt is not legally binding in all jurisdictions, respecting it demonstrates good faith and reduces the risk of legal action. Many sites explicitly allow scraping of public content while restricting access to user profiles, search results, or administrative pages.

Terms of service often prohibit automated access explicitly. Violating TOS can create legal liability, particularly in jurisdictions that recognize computer fraud and abuse statutes. In the United States, the Computer Fraud and Abuse Act (CFAA) has been used in scraping-related litigation, though the Supreme Court's Van Buren decision narrowed its scope. In the EU, the GDPR imposes strict requirements on collecting personal data through any means, including scraping.

The LinkedIn v. hiQ Labs case established that scraping publicly available data does not necessarily violate the CFAA, but this precedent has limitations and does not apply universally. Each scraping project should be evaluated based on the type of data being collected, its public availability, the presence of personal information, and the applicable jurisdiction.

Practical ethical guidelines include: respect robots.txt directives, honor rate limits, do not scrape behind authentication walls without permission, do not collect personally identifiable information without a lawful basis, identify yourself in your User-Agent string when possible, and contact the site owner if you plan to scrape at significant volume. Many sites offer official APIs or data feeds that provide structured access without the need for scraping.

Copyright applies to creative content regardless of how it is accessed. Scraping text, images, or other copyrighted material for redistribution or commercial use may constitute copyright infringement. Data facts (prices, dates, specifications) are generally not copyrightable, but the creative arrangement and presentation of those facts may be. Consult legal counsel when your scraping project involves substantial amounts of content from a single source.

Deep-Dive Guides