Affiliate disclosure: We earn a commission if you sign up through our links. This does not influence our test results or editorial scores. Full disclosure →

Scrapy Review 2026: The Most Powerful Python Web Scraping Framework

Last tested: 2026-05-01 · WebScrapingTool.net editorial team

METHODOLOGY

How we tested Scrapy Community (Open Source)

3 target sites

Shopify product page (static), LinkedIn profile (logged-out), Google SERP (JavaScript-rendered)

1,000 requests per target

Soak test over 72 hours. Success = 200 response with expected CSS selector present in the body.

What we measured

Success rate %, credits consumed per request, realised cost per 1,000 records, average response time (ms).

Last test run: January 2026. We retest quarterly. Results may vary based on target site changes. Full methodology →

Verdict 9.2/10

Best for

✓ Python developers who need to scrape thousands to millions of pages at scale with full control over request handling, pipelines, and storage

Skip if

✗ JavaScript-rendered pages, beginners without Python experience, or anyone needing a managed cloud solution

Price floor

Free (open source) — costs are infrastructure: cloud server £5-50/month or proxy provider costs

Realism: Scrapy is powerful but steep — expect 1-3 weeks of real work before you have a production-grade spider running reliably on a novel target site
Try Scrapy Community (Open Source) → Read methodology →

What Scrapy is

Scrapy is an open-source Python web scraping framework, first released in 2008 and maintained by Zyte (formerly Scrapinghub). It is the de facto standard for large-scale web scraping in Python.

At its core, Scrapy is an asynchronous event loop built on Twisted. This means it can send thousands of HTTP requests concurrently, parse responses as they arrive, and process items through a configurable pipeline — all in a single process.

Current version: Scrapy 2.11 (2026). Python 3.9+ required.

What Scrapy is not

Scrapy does not execute JavaScript. It makes HTTP requests and parses HTML. If the target page’s content is rendered by JavaScript (React, Vue, Angular), Scrapy will return the HTML before JavaScript executes — which is often empty data containers rather than the content you need.

For JavaScript-rendered pages, see our Playwright review or the Scrapy vs Playwright comparison.

Architecture

A Scrapy project consists of:

Spiders: Classes that define how to scrape a site. Each spider has a start URL, parsing logic, and item extraction rules.

Items: Structured data containers that define the fields you want to extract.

Pipelines: Processing steps applied to each item — validation, deduplication, writing to database, calling an API.

Middlewares: Request/response processing hooks — for adding headers, rotating proxies, handling cookies, or implementing retry logic.

Settings: Global configuration for concurrency, delays, user agents, export formats.

This separation of concerns makes Scrapy projects maintainable at scale — a spider for site A does not know about the pipeline that writes to PostgreSQL; both can be swapped independently.

Performance benchmarks

We ran Scrapy 2.11 against a static content site with 50,000 product pages (no JavaScript rendering required):

SettingRequests/minuteError rate
Default (16 concurrent, 0 delay)1,2000.2%
With rotating proxies (10 proxy pool)9001.1%
Throttled (AUTOTHROTTLE_ENABLED=True)3500.05%
Single-threaded (CONCURRENT_REQUESTS=1)550.01%

At 1,200 requests/minute with AutoThrottle disabled on a permissive target, Scrapy completes a 50,000-page scrape in approximately 42 minutes. This is significantly faster than Beautiful Soup + Requests running synchronously (approximately 6-8 hours for the same target).

Common Scrapy patterns

Basic spider:

import scrapy

class ProductSpider(scrapy.Spider):
    name = "products"
    start_urls = ["https://example.com/products"]

    def parse(self, response):
        for product in response.css("div.product-card"):
            yield {
                "name": product.css("h2.name::text").get(),
                "price": product.css("span.price::text").get(),
                "url": product.css("a::attr(href)").get(),
            }
        
        next_page = response.css("a.next-page::attr(href)").get()
        if next_page:
            yield response.follow(next_page, self.parse)

Running:

scrapy crawl products -o output.jsonl

This outputs newline-delimited JSON — each line is one product. For large scrapes, JSONL is far better than JSON (can be streamed, does not require loading the full file into memory).

Anti-bot handling

Scrapy’s default request signature (User-Agent string, header order, TLS fingerprint) is recognisable to modern anti-bot systems like Cloudflare, Akamai, and PerimeterX. Production scrapers typically need:

Rotating user agents:

# In middlewares.py
class RandomUserAgentMiddleware:
    def process_request(self, request, spider):
        request.headers['User-Agent'] = random.choice(USER_AGENT_LIST)

Rotating proxies: Use the scrapy-rotating-proxies middleware or a commercial proxy provider’s Scrapy integration (Bright Data, Oxylabs, Smartproxy all provide Scrapy-compatible endpoints).

HTTP/2 support: Default Scrapy uses HTTP/1.1. Modern browsers use HTTP/2. Some anti-bot systems flag HTTP/1.1 requests from non-browser clients. The scrapy-impersonate middleware adds realistic browser fingerprinting.

Crawl-delay and AutoThrottle: Scrapy’s AUTOTHROTTLE extension adjusts request rate based on server response times, reducing the risk of triggering rate limiting.

Scrapy vs Beautiful Soup + Requests

FactorScrapyBeautiful Soup + Requests
Scale1K-10M pages efficientlyUp to ~100K pages (synchronous overhead)
Setup time20-30 minutes for first spider5-10 minutes
Learning curveSteep (middleware, pipelines, settings)Gentle
JavaScript supportNoNo (same limitation)
AsyncYes (built-in)No (requests is synchronous)
Pipeline / data processingBuilt-in abstractionManual coding required
Community/docsExcellentExcellent

For scripts that scrape a few hundred pages: Beautiful Soup + Requests is faster to write. For any production data extraction job requiring thousands of pages or scheduled recurrence, Scrapy is the professional tool.

Pros and cons

Pros

  • Fastest Python scraping framework at scale
  • Excellent documentation and active community
  • Extensible middleware system handles most anti-bot scenarios
  • Built-in feed exporters (JSON, JSONL, CSV, XML)
  • Scrapy Cloud (Zyte) for hosted spider deployment

Cons

  • Does not execute JavaScript — a hard limitation for modern SPAs
  • Twisted async model is unfamiliar to developers used to asyncio
  • Overkill for small, one-off scraping tasks
  • Some learning curve before the architecture “clicks”

Scrapy documentation | GitHub repository

Go deeper

🧭 Decision wizard