Skip to content

docs: Add Migrating from Scrapy guide - #2013

Merged
vdusek merged 3 commits into
apify:masterfrom
Mantisus:scrapy-migration-guide
Jul 13, 2026
Merged

docs: Add Migrating from Scrapy guide#2013
vdusek merged 3 commits into
apify:masterfrom
Mantisus:scrapy-migration-guide

Conversation

@Mantisus

@Mantisus Mantisus commented Jul 2, 2026

Copy link
Copy Markdown
Collaborator

Description

  • Add a new guide for migrating from Scrapy to Crawlee. It provides a mapping of the core concepts and a set of side-by-side examples (Scrapy vs Crawlee) covering common cases, from a basic spider migration to error handling, login, and JavaScript rendering.

Issues

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a dedicated “Migrating from Scrapy” documentation guide to help Scrapy users translate core concepts and common patterns (routing, data passing, throttling, proxies, error handling, login, and JS rendering) into Crawlee for Python.

Changes:

  • Introduces a new docs/guides/scrapy_migration.mdx guide with a concept mapping table and side-by-side Scrapy vs Crawlee examples.
  • Adds Scrapy and Crawlee code snippets under docs/guides/code_examples/scrapy_migration/ to support the guide’s runnable and comparison blocks.
  • Updates Ruff per-file ignores for the Scrapy snippet files used purely for comparison.

Reviewed changes

Copilot reviewed 25 out of 25 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
pyproject.toml Adds Ruff per-file ignores for Scrapy tutorial snippets included as docs-only comparison code.
docs/guides/scrapy_migration.mdx New migration guide content with concept mapping and side-by-side examples.
docs/guides/code_examples/scrapy_migration/scrapy_throttling.py Scrapy AutoThrottle settings snippet for comparison.
docs/guides/code_examples/scrapy_migration/scrapy_quotes.py Scrapy quotes spider snippet for comparison.
docs/guides/code_examples/scrapy_migration/scrapy_proxy.py Scrapy rotating proxies/settings snippet for comparison.
docs/guides/code_examples/scrapy_migration/scrapy_playwright.py Scrapy + scrapy-playwright spider snippet for comparison.
docs/guides/code_examples/scrapy_migration/scrapy_playwright_settings.py scrapy-playwright settings snippet for comparison.
docs/guides/code_examples/scrapy_migration/scrapy_formrequest.py Scrapy FormRequest login snippet for comparison.
docs/guides/code_examples/scrapy_migration/scrapy_export.py Scrapy FEEDS export settings snippet for comparison.
docs/guides/code_examples/scrapy_migration/scrapy_errback.py Scrapy errback/retry behavior snippet for comparison.
docs/guides/code_examples/scrapy_migration/scrapy_crawlspider.py Scrapy CrawlSpider/Rules snippet for comparison.
docs/guides/code_examples/scrapy_migration/scrapy_concurrency.py Scrapy concurrency/download delay settings snippet for comparison.
docs/guides/code_examples/scrapy_migration/scrapy_cb_kwargs.py Scrapy cb_kwargs snippet for comparison.
docs/guides/code_examples/scrapy_migration/scrapy_authors.py Scrapy callback routing snippet for comparison.
docs/guides/code_examples/scrapy_migration/crawlee_user_data.py Crawlee equivalent showing Request.user_data + labeled handlers.
docs/guides/code_examples/scrapy_migration/crawlee_throttling.py Crawlee equivalent showing ThrottlingRequestManager usage.
docs/guides/code_examples/scrapy_migration/crawlee_quotes.py Crawlee equivalent of the canonical quotes spider.
docs/guides/code_examples/scrapy_migration/crawlee_proxy.py Crawlee equivalent proxy rotation via ProxyConfiguration.
docs/guides/code_examples/scrapy_migration/crawlee_post.py Crawlee equivalent of form submission/login with POST payload + headers.
docs/guides/code_examples/scrapy_migration/crawlee_playwright.py Crawlee PlaywrightCrawler example for JS-rendered pages.
docs/guides/code_examples/scrapy_migration/crawlee_labels.py Crawlee equivalent of callback routing using request labels and router handlers.
docs/guides/code_examples/scrapy_migration/crawlee_export.py Crawlee equivalent dataset export via export_data().
docs/guides/code_examples/scrapy_migration/crawlee_error_handling.py Crawlee equivalent error + failed-request handlers aligned with retry lifecycle.
docs/guides/code_examples/scrapy_migration/crawlee_crawlspider.py Crawlee equivalent rule-based crawling via enqueue_links() with include globs and labels.
docs/guides/code_examples/scrapy_migration/crawlee_concurrency.py Crawlee equivalent concurrency/rate settings via ConcurrencySettings.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread docs/guides/code_examples/scrapy_migration/crawlee_playwright.py
@Mantisus
Mantisus force-pushed the scrapy-migration-guide branch from d9cd4ad to d21b213 Compare July 2, 2026 21:58
@Mantisus
Mantisus marked this pull request as ready for review July 2, 2026 22:01
@Mantisus
Mantisus requested review from szaganek and vdusek July 2, 2026 22:03
@vdusek
vdusek removed the request for review from szaganek July 3, 2026 06:48
@vdusek

vdusek commented Jul 3, 2026

Copy link
Copy Markdown
Collaborator

Hi @Mantisus, I didn't tell you, request review from @szaganek only for the docs changes in SDK & Client repos.

@Mantisus
Mantisus requested a review from Pijukatel July 3, 2026 11:11
@Mantisus

Mantisus commented Jul 3, 2026

Copy link
Copy Markdown
Collaborator Author

Hi, @vdusek. Oh, got it, thanks for the information. @szaganek, sorry for the unnecessary ping.

@vdusek vdusek left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a few comments, but overall, this looks great 👍

Comment thread docs/guides/scrapy_migration.mdx Outdated
Comment thread docs/guides/scrapy_migration.mdx Outdated
Comment thread docs/guides/scrapy_migration.mdx
Comment thread docs/guides/code_examples/scrapy_migration/crawlee_concurrency.py
Comment thread docs/guides/code_examples/scrapy_migration/crawlee_export.py
Comment thread docs/guides/code_examples/scrapy_migration/crawlee_concurrency.py
Comment thread docs/guides/code_examples/scrapy_migration/crawlee_proxy.py
Comment thread docs/guides/scrapy_migration.mdx

@vdusek vdusek left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few more from Claude

Comment thread docs/guides/scrapy_migration.mdx Outdated
Comment thread docs/guides/scrapy_migration.mdx Outdated
Comment thread docs/guides/code_examples/scrapy_migration/crawlee_post.py
@Mantisus

Copy link
Copy Markdown
Collaborator Author

@honzajavorek, would you mind taking a look at this guide? I'd appreciate your feedback.

@Mantisus
Mantisus requested a review from vdusek July 12, 2026 12:52

@Pijukatel Pijukatel left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It reads well for someone who has never used Scrapy

@vdusek vdusek left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@honzajavorek

Copy link
Copy Markdown
Contributor

@Mantisus I'll take a look, thanks for the ping! But don't block on my review. Even if it's merged, I can review it ex-post and note down improvements we could make (if any).

@vdusek

vdusek commented Jul 13, 2026

Copy link
Copy Markdown
Collaborator

@Mantisus I'll take a look, thanks for the ping! But don't block on my review. Even if it's merged, I can review it ex-post and note down improvements we could make (if any).

Alright, let's merge it, thanks everyone 🙂

@vdusek
vdusek merged commit b44e9bc into apify:master Jul 13, 2026
35 checks passed

@honzajavorek honzajavorek left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trying and understanding Crawlee would be so much better for me if I had this tutorial at hand! Great job! I posted few comments and ideas for further improvement of the document, but I think there's nothing super serious. I didn't check the code itself much, I focused mainly on the text of the document.

I like asyncio more than Twisted, and I don't like classes, but the Scrapy code examples still often feel shorter and easier to my eyes. Not even mentioning the form example, which is just "well do it all yourself, pal". But that's up to designers of the framework to address… 😅 😛 But these days nobody reads the code anyway, it's all just agents, they say, so shorter or longer, I guess it doesn't matter.

Comment thread docs/guides/scrapy_migration.mdx

Both frameworks give you a request scheduler, a duplicate filter, retries, and a way to pull data out of pages. The way you wire those pieces together differs.

- Scrapy runs on the [Twisted](https://twisted.org/) reactor, and your callbacks are synchronous generators that `yield` items and requests. Crawlee runs on `asyncio`, and handlers are coroutines defined with `async def` that `await` helpers like <ApiLink to="class/PushDataFunction">`push_data`</ApiLink> and <ApiLink to="class/EnqueueLinksFunction">`enqueue_links`</ApiLink>. You write straight-line `async`/`await` code without a reactor.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know this difference is the most fundamental, but as a reader considering a switch who doesn't really care about deep technicalities like Twisted reactors, this is quite heavyweight start. I think casual Python users might know that asyncio exists, but the first sentence containing words like reactor, callbacks, synchronous generators, and yield, might be too much for many. I'd at least move this bullet point down the order and start with something more high level and straightforward, like the scrapy crawl, for example.

Comment thread docs/guides/scrapy_migration.mdx
Comment thread docs/guides/scrapy_migration.mdx
Comment thread docs/guides/scrapy_migration.mdx
Comment thread docs/guides/scrapy_migration.mdx
Comment thread docs/guides/scrapy_migration.mdx
Comment thread docs/guides/scrapy_migration.mdx
Comment thread docs/guides/scrapy_migration.mdx
Comment thread docs/guides/scrapy_migration.mdx
@Mantisus

Mantisus commented Jul 30, 2026

Copy link
Copy Markdown
Collaborator Author

@honzajavorek, thank you for reading the guide and for your suggestions on how to improve it. I'm glad you found it helpful!

I opened a new PR in which I implemented your suggestions: #2103

I like asyncio more than Twisted, and I don't like classes, but the Scrapy code examples still often feel shorter and easier to my eyes.

Yeah, Crawlee may seem unusual to those who have worked a lot with Scrapy.

Not even mentioning the form example, which is just "well do it all yourself, pal"

In this regard, I find Crawlee's approach more familiar and convenient 🙂. I hope this won't scare off any Scrapy users who might decide to try our framework. 😈

But these days nobody reads the code anyway

🙈

vdusek pushed a commit that referenced this pull request Jul 30, 2026
### Description

- Update and polish the `Migrating from Scrapy` guide

### Issues

- Follow-up: #2013
@honzajavorek

Copy link
Copy Markdown
Contributor

Thanks! I'll take a look at the PR 🚀

I don't think the form part will scare off anyone, it's just like… coming from Scrapy a thought comes to one's head: "folks, how hard is it to add one helper which does it for me, when it's given what should I do and it's always the same?" I don't remember the mime type from the top of my head, and I don't remember the stdlib import from the top of my head. And if someone needs something special, they can always skip the helper and just do exactly this, but for the most of us mere mortals, we'd have an out of the box tool.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Write a migration guide from Scrapy to Crawlee

6 participants