mrkeyoor.com_
Thu 24 Sept 20:00 UTC
Dataevaluationupdated 27 Aug 2026

scrapy review

Scrapy is a Python framework for crawling websites and turning responses into structured records. It coordinates requests, retries, parsing, link following, throttling, exports, and item processing so a scraper can grow beyond a loop around an HTTP client.

+59stars / 7d
Verdict

Our Scrapy run installed 67 packages in 36 seconds and built in 11 seconds, but the suite finished with 10 failures and 71 collection or setup errors, so reproduce the async test environment before contributing. Use Scrapy for a crawler that needs queues, politeness controls, exports, and extension points across many requests. Use Requests for a small extraction job, or a browser tool when rendered interaction is the work rather than an exception.

We ran it

Lab card: what happened when we ran scrapyScreenshot of scrapy (scrapy.org)
Install✓ · 36s67 packages · 97 MB
Build✓ · 11s
Tests✗ · 303s2460 passed · 10 failed · 49 skipped · 71 errors of 2541 (pytest)
Known vulns0(pip-audit)
Repo676 files~89,249 lines of source · 5.2 MB · 8 CI workflows · tests dir

Answers from our run

Does scrapy build from source?

Dependencies installed in 36 seconds (67 packages), and the build succeeded in 11 seconds. We cloned commit 11079cb into a clean Debian container with 3 CPUs and no project-specific setup.

Do scrapy's tests pass?

Not all of them: 2460 of 2541 passed and 10 failed when we ran the project's own test command (pytest), with 71 collection errors. Some failures need services or credentials a bare container does not have.

Does scrapy have known vulnerabilities in its dependencies?

pip-audit found none in the dependency tree at the time of our run.

Who should not use scrapy?

One-page scripts where a direct HTTP request and parser are easier to understand and maintain.

What are the alternatives to scrapy?

Requests, Playwright for Python, Crawlee for Python. Our Scrapy run installed 67 packages in 36 seconds and built in 11 seconds, but the suite finished with 10 failures and 71 collection or setup errors, so reproduce the async test environment before contributing.

Setup4/536-second install; productive spiders still need target-specific work
Docs5/5Strong tutorial, architecture, settings, and operations coverage
Community5/564,048 stars with active work through August 27, 2026
Maturity5/5Version 2.18.0 builds on a long-lived crawler architecture

Discussed on

  1. hnScrapy Tips from the Pros269 points
  2. hnPython 3 comes to Scrapy249 points
  3. hnHow to Crawl the Web Politely with Scrapy139 points
  4. hnSpiderKeeper: Admin UI for scrapy/open source scrapinghub107 points
  5. hnCrawl a website with scrapy and store extracted results with MongoDB93 points

Who it’s for

Python teams maintaining multi-page or multi-site crawlers with repeatable scheduling and output.
Data engineers who need CSS or XPath extraction, request middleware, item pipelines, retries, caching, and feed exports in one framework.
Operators who need per-domain concurrency limits, download delays, robots.txt handling, or automatic throttling.
Developers prepared to learn Scrapy's engine, scheduler, middleware, spider, and Twisted or asyncio boundaries.

Who it’s NOT for

One-page scripts where a direct HTTP request and parser are easier to understand and maintain.
Browser-first automation that needs clicks, screenshots, or a live DOM on most pages: Scrapy's own dynamic-content guide sends those cases to a headless browser.
Teams unwilling to inspect network requests on JavaScript-heavy sites: the docs prefer reproducing the underlying data request over rendering the page.
Developers who need to drop a crawler into an existing async application without integration work: the practices guide documents reactor and event-loop caveats.

Setup reality

Our sandbox installed Scrapy in 36 seconds, adding 67 packages and using 97 MB on disk. The build succeeded in 11 seconds. Tests exited with code 1 after 303 seconds: 2,460 passed, 10 failed, 49 skipped, and 71 collection or setup errors were reported out of 2,541.

The basic package needs Python 3.10 or newer. Real spiders also need target-specific selectors, request headers or sessions, crawl limits, storage, retry policy, and legal or contractual permission to collect the data. Browser-rendered pages may require Playwright or another browser tool.

The log tail repeatedly reports an unknown pytest.mark.asyncio, plus errors in console, decorator, reactor, signal, and other utility modules. It does not establish why the marker was unavailable. Pip-audit found 0 known vulnerabilities.

Scrapy earns its weight once a crawl becomes a system

A first scraper can be a request followed by a CSS selector. Scrapy becomes useful when that script needs a queue, concurrent downloads, retries, duplicate filtering, per-domain limits, item validation, and several output destinations. A spider yields requests and records while the engine coordinates the rest. That split keeps target-specific parsing separate from the machinery that decides what to fetch next and what to do when a request fails.

The codebase is substantial but contained. Our commit 11079cb checkout had 676 files, about 89,249 lines of source, and occupied 5.2 MB. Scrapy uses Twisted for event-driven networking, with current documentation also covering asyncio-oriented runners and an option to disable the Twisted reactor. Teams already running an async web service or task system should read those integration rules before starting crawls inside an existing process.

The engine handles queues while spiders own extraction

Scrapy's data flow has 9 documented stages. Initial requests move from a spider to the engine and scheduler, through downloader middleware to the downloader, then responses return through middleware to the spider. New requests loop back into the scheduler, while extracted items enter pipelines for cleaning, validation, or storage. That arrangement makes cookies, caching, proxies, retries, and instrumentation reusable across spiders instead of copied into each callback.

For output, the framework can export JSON, CSV, or XML to local files, FTP, or Amazon S3. CSS and XPath selectors cover HTML and XML, and an interactive shell helps test expressions against a response. Built-in controls include request delay, concurrent-request limits per domain, robots.txt handling, crawl-depth restrictions, HTTP caching, sessions, and AutoThrottle. These are practical features, but sensible defaults still depend on the target site's rules and capacity.

What happened when we ran it

Our sandbox installed 67 Python packages in 36 seconds and used 97 MB on disk. The build completed successfully in 11 seconds. Pip-audit found 0 known vulnerabilities in the installed dependency set. We tested commit 11079cb in a fresh Python 3.12 Debian container with 3 CPUs, 8 GB of RAM, no secrets, and no preconfigured external services.

The full test command failed after 303 seconds. Pytest reported 2,460 passed, 10 failed, 49 skipped, 17 expected failures, and 71 errors. The measurement block records 2,541 collected or set-up cases, while pytest's final timing line showed 287.01 seconds of test execution. A high passing count shows broad exercised behavior, but exit code 1 remains the outcome.

The log tail repeatedly says pytest.mark.asyncio is unknown and names collection errors across spider middleware, stats, async generators, asyncio helpers, console utilities, decorators, deferred helpers, reactors, signals, and resource tests. It does not prove whether a dependency, plugin configuration, or another condition caused the marker error. Our result therefore says this checkout did not pass in the stated sandbox, not that Scrapy's async runtime is broken.

JavaScript-heavy sites turn into request analysis or browser work

Scrapy downloads responses; it does not behave like a graphical browser by default. Its dynamic-content guide recommends finding the request that supplies the desired data, then reproducing its URL, method, headers, form fields, or body. Request.from_curl can translate a browser-exported curl command into a Scrapy request. This route usually transfers less data and parses more predictable structures than rendering a complete page.

When the data exists only in a live DOM, the same guide points to a headless browser. Playwright can be integrated through an asyncio reactor, and scrapy-playwright exists as a separate plugin. That boundary matters for project estimates. If 8 out of 10 targets require login flows, clicks, consent dialogs, and browser fingerprint work, browser automation is the core system and Scrapy may become an extra scheduling layer rather than the simplest foundation.

Version 2.18.0 improves HTTP support, not target stability

Release 2.18.0 arrived on August 20, 2026. It moved HttpxDownloadHandler to httpx2, removed the experimental label from the Twisted HTTP/2 handler, made Brotli and Zstandard support always available, added middleware for detecting copied request metadata, and changed late crawler attributes to raise RuntimeError before a crawl starts. These changes show active work on protocol handling and clearer failure behavior.

No crawler release can stabilize another company's markup, API, rate limits, or access policy. Selectors that pass today can return empty data after a frontend deploy. Production spiders need sample fixtures, field-level validation, response-status monitoring, and alerts for sudden record-count changes. Store enough response evidence to debug a parser without immediately recrawling the target, while observing the site's terms and avoiding retention of data you should not keep.

Current maintenance is strong, while the issue count needs context

GitHub showed 64,048 stars, 453 combined issues and pull requests, and a last push on August 26, 2026. Pull requests were active on August 27 for domain matching and disabled form controls. The repository also had 8 CI workflow files and a tests directory, with no Dockerfile in our scan. The combined open count includes feature work and pull requests, so it should not be presented as 453 bugs.

Scrapy remains the default serious choice for Python HTTP crawling because its abstractions match the work that appears after the first script succeeds. The 97 MB installed size and 11-second build are modest; learning the engine and operating target-specific failure detection are the larger costs. Adopt it when those shared controls will serve several spiders, and keep browser rendering outside the hot path unless the target leaves no cleaner source to request.

Alternatives

ProjectWhat it isPick it when
Requests gh↗A direct Python HTTP client for small scripts and tightly controlled request flows.pick this instead when a few known URLs and a parser are enough, without a crawler engine.
Playwright for PythonBrowser automation for pages that require JavaScript execution and user-like interaction.pick this instead when rendered DOM, clicks, screenshots, or browser state are central to extraction.
Crawlee for PythonA Python crawling toolkit with HTTP and browser-oriented crawler options.pick this instead when one framework should cover both ordinary HTTP crawling and browser automation.

What people are saying

  1. [github-trending] scrapy/scrapy

Sources

  1. Scrapy README
  2. Scrapy repository facts
  3. Scrapy 2.18.0 release
  4. Scrapy at a glance
  5. Scrapy architecture overview
  6. Selecting dynamically loaded content

More data reviews

go-stock · sqlitebrowser · hydradb · DouYin_Spider · helix-db · abu · the whole board →