Scrapy-Redis 即开即用功能模块
📦 核心模块一览
arduino
scrapy_redis/
├── scheduler.py → 分布式调度器
├── dupefilter.py → 分布式去重过滤器
├── queue.py → 多种 Redis 队列实现
├── spider.py → 分布式 Spider 基类
├── pipelines.py → Redis Item 管道
├── connection.py → Redis 连接管理
└── picklecompat.py → 序列化兼容层
1️⃣ 分布式调度器 Scheduler
替换 Scrapy 默认调度器,核心枢纽
python
# settings.py
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
SCHEDULER_PERSIST = True # 重启后队列不清空,断点续爬
SCHEDULER_FLUSH_ON_START = False # 启动时不清空队列
能力:
- 将所有待爬 URL 统一存入 Redis,多节点共享
- 支持持久化(进程崩溃后恢复队列)
- 自动与去重器配合
2️⃣ 分布式去重器 RFPDupeFilter
基于 Redis Set 的全局去重
python
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
原理:
scss
URL → fingerprint(sha1) → SADD redis_key →
已存在 → 丢弃
不存在 → 入队
⚠️ 默认用 Redis Set,内存占用较大;大规模需替换为 Bloom Filter (
scrapy-redis-blfilter)
3️⃣ 三种 Redis 队列 Queue
| 队列类 | Redis 结构 | 特性 |
|---|---|---|
SpiderQueue |
List (FIFO) | 默认,先进先出 |
SpiderStack |
List (LIFO) | 后进先出,深度优先 |
SpiderPriorityQueue |
ZSet | 按优先级排序 ✅ 推荐 |
python
# 切换队列类型
SCHEDULER_QUEUE_CLASS = "scrapy_redis.queue.SpiderPriorityQueue"
4️⃣ 分布式 Spider 基类
RedisSpider --- 从 Redis 读取起始 URL
python
from scrapy_redis.spiders import RedisSpider
class MySpider(RedisSpider):
name = "my_spider"
redis_key = "my_spider:start_urls" # 监听的 Redis key
def parse(self, response):
...
bash
# 外部注入起始任务
redis-cli LPUSH my_spider:start_urls "https://example.com"
RedisCrawlSpider --- 带规则的分布式爬虫
python
from scrapy_redis.spiders import RedisCrawlSpider
from scrapy.spiders import Rule
from scrapy.linkextractors import LinkExtractor
class MyCrawler(RedisCrawlSpider):
name = "crawler"
redis_key = "crawler:start_urls"
rules = (
Rule(LinkExtractor(allow=r"/article/"), callback="parse_item"),
)
5️⃣ Redis Item Pipeline
将爬取结果直接写入 Redis
python
ITEM_PIPELINES = {
"scrapy_redis.pipelines.RedisPipeline": 300
}
REDIS_ITEMS_KEY = "%(spider)s:items" # 存储 key
REDIS_ITEMS_SERIALIZER = "json" # 序列化格式
通常作为中间缓冲,再由消费者进程写入 MySQL/MongoDB
6️⃣ 连接管理 connection
统一管理 Redis 连接,支持多种配置方式:
python
# 方式1:URL
REDIS_URL = "redis://:password@host:6379/0"
# 方式2:分项配置
REDIS_HOST = "127.0.0.1"
REDIS_PORT = 6379
REDIS_DB = 0
REDIS_PARAMS = {"password": "xxx", "socket_timeout": 30}
功能模块关系图
scss
[外部] LPUSH start_urls
↓
RedisSpider (监听)
↓
Scheduler (调度器) ←→ Redis Queue (待爬 URL)
↓ ↑
RFPDupeFilter (去重) 新发现的 URL
↓
Scrapy 下载器 → parse()
↓
Item Pipeline → RedisPipeline → Redis Items
快速启用配置模板
python
# settings.py 最小配置
REDIS_URL = "redis://localhost:6379/0"
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
SCHEDULER_PERSIST = True
SCHEDULER_QUEUE_CLASS = "scrapy_redis.queue.SpiderPriorityQueue"
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
ITEM_PIPELINES = {
"scrapy_redis.pipelines.RedisPipeline": 300
}
6 个模块,settings.py 改 5 行,单机 Scrapy 即变分布式。