Web Scraping Without Getting Blocked: A Developer's Guide

Published July 24, 2026 · 7 min read

Getting blocked is the #1 frustration in web scraping. You write the code, it works in testing, you deploy it — and within hours, your IP is banned and you're staring at Cloudflare challenge pages instead of data.

Here's what actually causes blocks, and how to avoid them — from someone who's been on both sides of the cat-and-mouse game.

Why Sites Block Scrapers

Sites don't block scrapers because they hate developers. They block scrapers because:

Understanding why matters because it tells you how to scrape responsibly in ways that don't trigger defenses.

The Anti-Bot Detection Stack

Modern websites use a layered detection system. Here's what you're up against:

LayerWhat It ChecksDifficulty to Bypass
1. HTTP headersUser-Agent, Accept-Language, missing browser headersEasy
2. IP reputationDatacenter IPs, known proxy ranges, request velocityMedium
3. TLS fingerprintTLS handshake characteristics (JA3/JA4 fingerprint)Hard
4. JavaScript challengesCloudflare Turnstile, reCAPTCHA, JS execution checksHard
5. Behavioral analysisMouse movement, scroll patterns, timing between clicksVery Hard

What Actually Works

1. Respect robots.txt (seriously)

The easiest way to get blocked is to ignore robots.txt. If a site explicitly disallows a path, scraping it will trigger alarms fast. Check it first:

curl -s https://target-site.com/robots.txt | grep Disallow

2. Use Real Browser Headers

The default python-requests/2.31.0 user agent is a giant "I'M A BOT" flag. Use a real Chrome user agent with a full header set:

const headers = {
  'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
  'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
  'Accept-Language': 'en-US,en;q=0.9',
  'Accept-Encoding': 'gzip, deflate, br',
  'DNT': '1',
  'Connection': 'keep-alive',
  'Upgrade-Insecure-Requests': '1',
  'Sec-Fetch-Dest': 'document',
  'Sec-Fetch-Mode': 'navigate',
  'Sec-Fetch-Site': 'none',
  'Sec-Fetch-User': '?1',
  'Cache-Control': 'max-age=0'
};
Pro tip: Missing Sec-Fetch-* headers are a dead giveaway. Chrome sends them on every request. Python's requests library doesn't. This alone triggers anti-bot detection on Cloudflare-protected sites.

3. Throttle Your Requests

The single biggest mistake: hitting a site too fast. A real human takes 3-30 seconds between page loads. A scraper requesting 10 pages/second looks like an attack.

// Good: random delays between requests
async function scrapeWithDelay(urls) {
  for (const url of urls) {
    await extractPage(url);
    // Random delay between 2-8 seconds
    const delay = 2000 + Math.random() * 6000;
    await new Promise(r => setTimeout(r, delay));
  }
}

4. Use a Real Browser for JavaScript-Heavy Sites

HTTP requests fail on SPAs, React apps, and any site that loads content with JavaScript. You'll get an empty <div id="root"> instead of actual data. This is where headless browsers come in — but running them yourself is a maintenance nightmare.

ExtractAPI runs every request through a real Chromium browser, so you get the rendered page without managing browser infrastructure:

curl -X POST https://extractapi.app/v1/extract \
  -H "Authorization: Bearer $EXTRACT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://react-ecommerce-site.com/products/123",
    "waitFor": ".product-details-loaded",
    "javascript": true
  }'

5. Rotate Patterns, Not Just IPs

Anti-bot systems profile behavior, not just IPs. If you request pages at exactly 3.0-second intervals, always visit pages in sequential order, and never load images or CSS — you'll get flagged even with rotating residential IPs.

Add randomness to:

When to Stop DIY-ing and Use an API

You should use a scraping API when:

The real cost of DIY scraping: A $9/month scraping API looks expensive until you account for the 20+ hours/month you spend debugging blocks, updating browser automation, and babysitting proxy rotations. Your time is worth more than $0.45/hour.
Stop Fighting Anti-Bot — Start at $9/month