Web scraping framework · async crawling at scale · verified against Scrapy 2.18 (2026)

Scrapy cheat sheet

Scrapy is the framework for large-scale web scraping: you write a Spider that issues Requests and parses the Responses, yielding scraped items and follow-up requests. It handles concurrency, throttling, retries, cookies, and export — an async engine (native async/await since 2.14). Great for structured data collection to feed ML/analytics. This sheet targets Scrapy 2.18 (Python 3.10+).

project & spider selectors (extract) requests & following items & pipelines settings & tools gotcha most common

Verified 2026-08-24 against the official docs at docs.scrapy.org (Scrapy 2.18) and scrapy.org. Maintained by Zyte. Scrape responsibly — respect robots.txt, rate limits & terms of service.

Outline

A spider yields two things from parse: items (data) and requests (more pages to crawl). Everything else is extracting fields and configuring behavior.

Build

  1. 1 · Project & spider
  2. 2 · parse & run

Extract

  1. 3 · CSS & XPath selectors
  2. 4 · get / getall / attrib

Crawl

  1. 5 · Following links
  2. 6 · Requests, meta, forms

Structure

  1. 7 · Items & loaders
  2. 8 · Pipelines & export

Operate

  1. 9 · Settings & the shell
  2. 10 · Gotchas
  3. Worth memorizing

Build a Spider

Scaffold a project, write the crawl entry point.

1Project & spider2.18
2parse & runthe callback

Extract

Pull fields out of the response.

3CSS & XPath selectorsquery the DOM
4get / getall / attribto Python values

Crawl

Follow links and craft requests.

5Following linkspagination & detail
6Requests, meta, formscustomize

Structure & Store

Typed items and post-processing.

7Items & loadersstructured output
8Pipelines & exportprocess items

Operate

Tune behavior and debug interactively.

9Settings & the shellbe a good citizen
!Common gotchasread before shipping

Worth memorizing

yield items AND requestsparse returns data (dicts/Items) and follow-up Requests
::text and ::attr(href)Scrapy's CSS pseudo-elements; .get()/.getall()
get() is None-safeget(default="") before converting types
response.follow for paginationresolves relative URLs; follow_all for many
cb_kwargs to pass datacleaner than meta for callback arguments
scrapy shell "url"perfect selectors interactively before coding
check for a hidden JSON APIresponse.json() beats parsing JS-rendered HTML
AutoThrottle + robots + delaypoliteness = not getting banned
pipelines process every itemclean/validate/store; DropItem to discard