随着爬虫场景的不断升级,Scrapy 虽然成熟稳定,但在异步支持、WebSocket 和现代请求库等方面有一些局限。
scrapy_cffi
是在 Scrapy 风格基础上重构的异步爬虫框架,支持更现代的请求库、扩展机制和异步 DB/MQ 管理。
通过这篇教程,你可以快速创建自己的异步爬虫项目,并体验框架的核心特性。
1.为什么要重构 Scrapy
Scrapy 本身虽然功能强大,但存在一些痛点:
- IDE 提示有限:代码提示和补全不够友好
- 异步支持弱:asyncio 协程能力有限,WebSocket 支持缺失
- 不支持 TLS/JA3 指纹等高级特性
重构目标:
- 保留 Scrapy 风格,降低学习成本
- 使用现代请求库
curl_cffi
替代twisted
- 支持自定义扩展、异步数据库和消息队列管理
💡如果你已经熟悉 Scrapy,上手
scrapy_cffi
非常快。
2.快速构建
2.1 安装框架
bash
pip install scrapy_cffi
2.1 创建项目
bash
# 新建项目
scrapy-cffi startproject <project_name>
cd <project_name>
# 生成爬虫
scrapy-cffi genspider <spider_name> <domain>
"""
genspider 后可选参数:
-r 创建 redis 爬虫
-m 创建 rabbitmq 爬虫
-k 启用 kafka 日志队列
"""
# 运行爬虫
python runner.py
3.配置
框架的配置基于 pydantic
,支持类型校验和 IDE
自动补全。大部分简单请求参数(如并发数、延迟、重试、UA 等)开箱即用,下面是一些配置注意事项:
-
MAX_GLOBAL_CONCURRENT_TASKS
未配置可能触发
fd 上限
,尤其是 Windows。 -
QUEUE_NAME
只在
run_spider
模式下有效;在run_all_spiders
或分布式 WebSocket 爬虫下必须单独配置,否则会抢队列。 -
数据库/消息队列(Redis / RabbitMQ / Kafka)
只需配置 URL 和集群相关选项,框架会自动维护连接。
-
.env
与settings.py
支持自动转换,部署更方便,不用担心配置冲突。
更多配置见 docs
4.爬虫
框架完全异步,但爬虫层可以灵活编写:
- 支持异步/同步方法
- 支持
yield
或直接return
请求和数据项 - 保持 Scrapy 风格
python
async def parse(self, response):
# 异步请求示例
yield HttpRequest(url="https://example.com")
yield Item(name="demo")
核心逻辑:定义函数产出请求和 Item,其余由框架管理。
5.拦截器与管道
- 延续 Scrapy 风格,
middlewares
改名为interceptors
- 支持自定义下载器中间件、拦截器、Item Pipeline 和扩展组件
- 使用习惯几乎与 Scrapy 一致
6.其他扩展
6.1 json 提取
- 支持 Scrapy 同款
xpath/css/re
选择器 - 自动解析嵌入或异常 JSON
- 直接提取指定 key 的 value
- 适合抓取 API、页面嵌入数据或日志文本等
6.2 protobuf 编码解码
- 使用
bbpb
支持 Protobuf 编码与解码 - 直接操作 Python 对象,无需 scheme
- 适合处理二进制接口数据
6.3 支持 C 扩展注入
- 将性能关键任务通过 C 扩展加速
- 框架支持全局注入,任意代码中直接使用
- 避免模块重名即可
推荐项目结构:
bash
/project
|
|- cpy_resources
| |- module1_dir
| | |- build_dir
| | | |- libmodule1.dll # Windows 编译的C扩展二进制文件
| | | |- libmodule1.so # Linux 编译的 C 扩展二进制文件
| | | |- libmodule1.dylib # macOS 编译的 C 扩展二进制文件
| | |
| | |- module1.pyi # 可选,用于 ide 代码提示
| | |- fallback.py # C 扩展加载失败后可以尝试加载的纯 python 实现
| | |- wrapper.py # 通过 ctypes 加载 C 扩展的核心实现
| |
| |- module2_dir
| |- ...
|
|- extensions
|- interceptors
|- items
|- pipelines
|- spiders
|- settings.py
|- runner.py
然后在配置 settings.py
中定义:
python
settings.CPY_EXTENSIONS.DIR = "cpy_extensions"
from scrapy_cffi.models import CPYExtension
settings.CPY_EXTENSIONS.RESOURCES = [
CPYExtension(module_name="module1_dir")
]
框架会将扩展程序注入全局(应当避免和某些模块重名),在任意代码中直接使用
python
import module1_dir
6.4 hook 插件
- 通过各组件
hooks
提供核心功能 - 不暴露所有方法,确保框架稳定性
6.5 模块化设计
- 数据库/消息队列管理类及工具类可单独使用
- 可组合为完整爬虫程序或独立爬虫工具库
7.快速 demo
通过 CLI 可以直接生成可运行 demo 项目:
bash
scrapy-cffi demo
"""
可选参数:
-r 创建 redis demo
-m 创建 rabbitmq demo
-k 启用 kafka 日志队列