断点续爬需scheduler_persist=true、redis持久化队列及正确去重机制三者协同生效;若仅配置开关而未确保调度器接管队列、redis开启aof/rdb、任务真实写入对应键(如myspider:requests),或dupefilter_class未正确替换并指向同一redis实例,则重启后仍会从头爬取。

断点续爬不是靠“重启就能自动接上”,而是靠 SCHEDULER_PERSIST=True + Redis 持久化队列 + 正确的去重机制三者共同生效;缺一不可,否则重启后仍会从头开始。
为什么加了 SCHEDULER_PERSIST=True 还是从头爬?
这是最常踩的坑:只配了调度器和去重类,却忘了确认 Redis 是否真正写入了任务数据。Scrapy-Redis 默认在爬虫关闭时清空队列(除非显式开启持久化),而 SCHEDULER_PERSIST=True 必须配合 SCHEDULER="scrapy_redis.scheduler.Scheduler" 才起作用。
-
SCHEDULER_PERSIST=True是开关,但它的效果依赖于调度器是否真的接管了队列 —— 如果SCHEDULER配错(比如漏写、拼错成scrapy_redis.scheduler.Scheduler少了个s),它就完全不生效 - Redis 本身默认不开启 AOF 或 RDB 持久化,如果机器断电或 Redis 服务重启,
start_urls入队后的请求可能已丢失 —— 建议在redis.conf中启用appendonly yes - 检查 Redis 中是否存在对应键:
redis-cli keys "myspider:requests"(队列)、"myspider:dupefilter"(去重集合),若为空,说明任务根本没进 Redis
DUPEFILTER_CLASS 用错会导致重复抓取
原生 Scrapy 的 RFPDupeFilter 只存内存,换成 scrapy_redis.dupefilter.RFPDupeFilter 后,指纹才真正落库。但要注意两点:
仅使用 Python 将 Claw Code 虚拟化框架与 OpenClaw 集成,提供 184 种工具和 200 多条命令,用于安全分析和代码质量...
- 必须确保
REDIS_URL或REDIS_HOST/REDIS_PORT配置与调度器一致,否则去重集合写到另一个 Redis 实例里,等于没写 - 如果爬虫启用了
ROBOTSTXT_OBEY=True且目标站 robots.txt 动态变化,可能导致同一 URL 因 User-Agent 或路径参数微调被算作不同指纹 —— 这种情况建议在request_fingerprint()中自定义清洗逻辑 - 去重集合名默认为
spidername:dupefilter,若多个爬虫共用一个 Redis DB 且名字冲突,会互相干扰 —— 可通过DUPEFILTER_KEY参数指定唯一键名
分布式下多个爬虫抢同一个 URL 怎么不重复?
靠 Redis 的原子操作,不是靠 Python 层锁。关键在队列类型和消费方式:
- 默认队列是
SpiderQueue(基于 List 的 FIFO),用RPOP拿任务 —— 它天然原子,多实例并发RPOP不会返回同一 URL - 若需优先级调度,改用
SpiderPriorityQueue(基于 Sorted Set),分数高者先出,但注意:分数相同则顺序不确定,建议分数带时间戳避免并列 - 切勿在
start_requests()中直接yield Request(url)—— 这类请求走的是内存队列,绕过 Redis;所有初始 URL 应通过redis-cli LPUSH myspider:start_urls "https://..."注入,或重写start_requests从 Redis 读取 - 检查日志中是否有
DEBUG: Received <get ...> from redis</get>,没有则说明请求没走 Redis 调度器
如何验证断点续爬真正在工作?
别等爬到一半断电再试,现场验证更快:
- 启动爬虫后,立刻
redis-cli LLEN "myspider:requests"看队列长度是否 >0;中断后再次LLEN,应保持不变 - 手动往队列塞一个新 URL:
redis-cli LPUSH myspider:requests "https://example.com/test",重启爬虫后观察是否抓取该页 - 抓取若干页后,停掉爬虫,用
redis-cli SMEMBERS "myspider:dupefilter"查看已去重 URL 列表,重启后再抓同一页,应无 log 显示 “filtered” 以外的请求发出 - 注意:
scrapy_redis.pipelines.RedisPipeline仅缓存 Item,不影响断点逻辑 —— 它只是把数据暂存 Redis,实际入库需另配 pipeline,别误以为开了它就等于断点完整
真正麻烦的不是配置几行代码,而是 Redis 键空间管理 —— 比如爬虫名变更后旧键残留、测试时反复启停导致 dupefilter 膨胀、生产环境多个 spider 共享 db 却没隔离 key 前缀。这些不会报错,但会让断点行为变得不可预测。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










