Scrapy 架构与核心组件
前置知识
本文基于模型知识整理,建议核对官方文档(见 参考资料)。
一句话定义
Scrapy 是异步采集框架,把「调度、下载、解析、清洗、存储」拆成职责分离的组件;理解其数据流就能把脚本级经验平移成工程级项目。
为什么重要
脚本在三类需求前必然崩塌:数千页面的调度、字段统一清洗、失败任务的追踪。Scrapy 用成熟组件解决了这三件事,其「Spider 管解析、Pipeline 管落地」的分层思想也是一切采集工程的设计范本。
前置知识
kp-006、kp-010;对「框架 = 组件 + 数据流」有直觉。
核心概念
- Engine:中枢,协调所有组件间的数据流。
- Scheduler:请求队列(内存/持久化),决定下一个发谁。
- Downloader:执行 HTTP 请求,返回 Response。
- Spider:业务核心,定义「从哪开始、怎么解析、产出什么」。
- Item Pipeline:对抽取结果做清洗、去重、存储的流水线。
- Downloader / Spider Middleware:请求发出前、响应进入 Spider 前的统一拦截层(改头、重试、UA 轮换都挂这里)。
原理与机制
一次请求的完整数据流(记熟它,报错时才能定位在哪一环):
Spider(start_requests)
→ Engine → Scheduler(入队)
→ Engine → Downloader(经下载中间件) → HTTP
← Response(经下载中间件) → Engine → Spider.parse
parse 产出: Item → Item Pipelines(1..N) / 新 Request → Scheduler
最小项目骨架:
# spiders/books.py
import scrapy
class BooksSpider(scrapy.Spider):
name = "books"
start_urls = ["https://books.toscrape.com/"]
def parse(self, response): # 列表页: 产出详情请求
for href in response.css("article.product_pod h3 a::attr(href)"):
yield response.follow(href, callback=self.parse_detail)
nxt = response.css("li.next a::attr(href)").get()
if nxt:
yield response.follow(nxt) # 翻页也走调度器
def parse_detail(self, response): # 详情页: 产出 Item
yield {
"title": response.css("h1::text").get(),
"price": response.css("p.price_color::text").get(),
}
# pipelines.py —— 职责: 清洗与落库, 绝不在 Spider 里做
class CleanPipeline:
def process_item(self, item, spider):
item["price"] = float(item["price"].replace("£", ""))
return item # 返回才继续流入下一 Pipeline
settings 三件套(礼貌抓取的框架化开关,对应 kp-017):ROBOTSTXT_OBEY=True、AUTOTHROTTLE_ENABLED=True、CONCURRENT_REQUESTS_PER_DOMAIN=1。
实例或案例
调试选择器不必整跑 Spider:scrapy shell "https://books.toscrape.com/" 进入交互环境,直接 response.css(...) 试表达式——Scrapy 的开发节奏是 shell 里调通选择器,再抄回 Spider,效率数倍于 print 调试。
常见误区
- 误区一:在 Spider 里写数据库写入。 职责错位导致无法复用清洗逻辑;存储/清洗/去重一律放 Pipeline。
- 误区二:把所有请求当回调串。 翻页与详情请求应
yield回调度器统一排队限速,而不是在回调里自己循环发。 - 误区三:忽略框架默认值。
ROBOTSTXT_OBEY默认开启却被随手关掉;CONCURRENT_REQUESTS调高前先想 kp-004。
自测题
- 一条请求在 Scrapy 里经过哪些组件?
答:Spider 产出 → Engine → Scheduler 排队 → Downloader(过下载中间件)→ Response → Spider 回调解析 → Item 入 Pipeline / 新请求回 Scheduler。
- Item 与 Pipeline 的分工?
答:Spider 只负责抽取成结构化 Item;清洗、去重、校验、存储在 Pipeline 串联完成。
- 下载中间件的典型用途?
答:统一改请求头/UA 轮换、代理注入、响应级重试与异常转换。
与其他知识点的关系
kp-017 的限速被 AUTOTHROTTLE 框架化;kp-021 的去重由调度器内建;kp-022 的 scrapy-redis 把 Scheduler 换成共享 Redis 队列即成分布式。
延伸阅读
Scrapy 官方文档「Architecture overview」(数据流图务必读);Tutorial 章节。