scrapy-redis 中 dupefilter 缺失问题解析
先给结论: 在 scrapy-redis 爬虫中,如果不重写 是否触发去重,取决于 关键就在 逻辑链路: 自己重写示例: 不影响: RedisSpider 作为分布式爬虫入口,URL 是从 Redis 队列 所以默认 核心结论: 不是没用 Redis Scheduler,而是
dont_filter=True 跳过了去重器,所以 Redis 里不会创建 dupefilter 这个 Key。问题背景
start_requests(),而是使用父类默认方法,会发现 Redis 里没有 xxx:dupefilter 这个 Set。调度流程
Spider → Engine → Scheduler → DupeFilter(去重器)request.dont_filter 的值。父类 start_requests() 做了什么?
scrapy_redis.spiders.RedisSpider 默认实现大致如下:yield Request(url, dont_filter=True)dont_filter=True。调度器内部逻辑
Scheduler.enqueue_request() 中有如下判断:if not request.dont_filter:
if self.df.request_seen(request):
return Falsedont_filter=True → 跳过去重逻辑request_seen()SADD top250:dupefilter fingerprint对比验证
场景 方式 Redis dupefilter 使用父类默认 start_requests()dont_filter=True❌ 不创建 自己重写,使用默认 Request dont_filter=False(默认)✅ 创建 def start_requests(self):
yield scrapy.Request(url) # dont_filter 默认为 False,会触发去重dont_filter=True 的影响范围
dont_filter=True 只影响:为什么 scrapy-redis 这样设计?
lpush 进来的,设计假设是:dont_filter=True,跳过去重。总结
问题 答案 是否使用 Redis Scheduler? 是 为什么没有 dupefilter? 因为 dont_filter=True,跳过了去重是不是没用 Redis? 不是 去重什么时候发生? 当 dont_filter=False 时本质理解:
dont_filter 控制的是单个 Request 是否走去重流程,与使用哪个 Scheduler 无关。