Scrapy 是一个基于 Twisted 异步网络框架 构建的高效爬虫框架,其核心架构采用 事件驱动模型,支持高并发、可扩展的网页抓取。以下是其核心组件及数据流示意图:
+-------------------------------------------------+
| Scrapy Engine | <--> 控制数据流
+--------+------------------+---------------------+
| |
v v
+----------------+ +-----------------+
| Scheduler | | Downloader | <--> 下载请求
+----------------+ +-----------------+
^ |
| v
+----------------+ +-----------------+
| Spiders | | Item Pipeline | <--> 数据处理
+----------------+ +-----------------+
控制所有组件的数据流和事件调度。
触发事件(如请求生成、响应处理)并协调各模块工作。
管理待爬取的请求队列(Request Queue)。
支持去重(通过 Request Fingerprint)和优先级调度。
负责发送 HTTP 请求并接收响应。
基于 Twisted 实现异步非阻塞下载。
用户编写的爬虫代码,定义如何解析响应(如提取链接或数据)。
生成新的 Request 或 Item 对象。
处理 Spider 提取的 Item(如数据清洗、存储到数据库)。
支持多级管道串联处理(例如去重 -> 验证 -> 存储)。
Downloader Middlewares:拦截请求和响应(如更换 User-Agent、处理代理)。
Spider Middlewares:处理 Spider 的输入和输出(如过滤无效请求)。
Scrapy 的工作流程如下(以一次请求为例):
yield scrapy.Request(url, callback=self.parse)
Scheduler 分配请求优先级并去重。
通过 Twisted 的异步机制处理网络 IO,避免阻塞。
响应经过 Downloader Middlewares 处理(如重试失败请求)。
Spider 的 parse() 方法提取数据或生成新请求。
数据依次通过多个 Pipeline 进行清洗、存储等操作。
Scrapy 基于 Twisted 的 Reactor 模式实现异步 IO,通过单线程处理高并发请求。
当一个请求等待响应时,引擎会处理其他请求,最大化利用网络带宽。
通过哈希算法(如 sha1)生成请求的唯一指纹,存储于内存或数据库(如 scrapy.dupefilters.RFPDupeFilter)。
海量 URL 去重时可使用布隆过滤器减少内存占用。
典型应用场景:
class RandomUserAgentMiddleware:
def process_request(self, request, spider):
request.headers['User-Agent'] = random.choice(USER_AGENTS)
可修改 Spider 的输入(如过滤重复 Item)或输出(如修改 Request 参数)。
class ArticleItem(scrapy.Item):
title = scrapy.Field()
content = scrapy.Field()
class MongoPipeline:
def process_item(self, item, spider):
self.db[spider.name].insert_one(dict(item))
return item
可监控爬虫运行状态(如统计请求耗时、错误率):
class StatsExtension:
def spider_opened(self, spider):
self.stats.set_value('start_time', datetime.now())
动态页面:通过 scrapy-splash 或 selenium 集成渲染 JavaScript。
分布式:结合 scrapy-redis 实现分布式爬取。
调整 CONCURRENT_REQUESTS(默认 16)和 DOWNLOAD_DELAY。
启用 AUTOTHROTTLE 自动限速避免被封禁。
启用 HTTPCACHE 缓存已下载页面(调试或增量爬取时有用)。
使用 JOBDIR 保存任务状态,支持断点续爬。
结构化数据抓取:新闻、电商商品、社交媒体内容。
大规模爬虫:通过分布式扩展(如 scrapy-redis)处理千万级页面。
复杂数据处理:需要清洗、去重、存储到多种数据库的场景。
六、总结
Scrapy 通过 模块化设计
和 异步事件驱动模型
实现了高效的网页抓取。其核心优势在于:
清晰的组件分工和数据流控制;
灵活的中间件和扩展机制;
基于 Twisted 的高性能异步下载。