redisspider启动没反应最常见原因是redis_key与lpush的key不一致或redis连接参数配置错误;必须确保key完全匹配、redis可访问(ping返回pong)、密码等参数显式正确设置。

Scrapy 本身不支持分布式,必须靠 scrapy-redis 替换默认调度器和去重器,才能让多个爬虫实例共享同一套 URL 队列。核心不是“部署多台机器”,而是“所有节点是否从同一个 Redis 列表(或 zset)里取 request、往同一个集合里写指纹”。
为什么 RedisSpider 启动后没反应?
最常见原因是 redis_key 在爬虫类里写的值,和 redis-cli lpush 推入的 key 不一致,或者 Redis 连接参数(REDIS_HOST、REDIS_PORT)在 settings.py 里配错导致根本连不上。
-
redis_key = 'my_spider:start_urls'必须和settings.py中的REDIS_START_URLS_KEY = 'my_spider:start_urls'保持一致(如果用了这个配置),否则RedisSpider不会主动监听该 key - 启动前务必手动确认 Redis 是否可访问:
redis-cli -h 192.168.1.100 -p 6379 ping返回PONG才算通 - 若使用密码,
REDIS_PASSWORD必须显式设置,空字符串''和未定义是两回事;且某些旧版scrapy-redis不支持带用户名的 Redis URL 格式
SCHEDULER_PERSIST=True 的实际影响
这个配置决定爬虫中断后,Redis 里的待爬 URL 是否保留。设为 True 是分布式常态,但容易忽略两个副作用:
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 每次重启爬虫,它会继续消费上次遗留的 request —— 如果你改了
parse逻辑但没清 Redis,旧 request 可能触发新代码中的 KeyError 或解析异常 - 任务队列不会自动清空,
lrange my_spider:start_urls 0 -1能查到全部 pending URL;想重跑需手动del my_spider:start_urls或用flushdb - 若同时跑多个不同爬虫共用一个 Redis DB,
SCHEDULER_PERSIST=True会让它们的队列互相污染,建议按爬虫名划分 DB(REDIS_PARAMS={'db': 1})
URL 去重失效的典型场景
DUPEFILTER_CLASS="scrapy_redis.dupefilter.RFPDupeFilter" 看似开箱即用,但实际中常因以下原因漏判重复:
- GET 参数顺序不同(
/a?x=1&y=2vs/a?y=2&x=1)会被视为两个指纹 ——RFPDupeFilter默认不做参数标准化,需自己继承重写request_fingerprint - 带 Cookie 或 User-Agent 的请求,指纹会把 headers 也算进去;若多个 worker 的
DEFAULT_REQUEST_HEADERS不一致,相同 URL 也会被重复抓 - Redis 连接超时或网络抖动时,
dupefilter的sismember操作可能失败并静默跳过,表现为偶发重复 —— 建议监控 Redis 的rejected_connections和evicted_keys
如何验证多个 worker 确实在协同工作?
不要只看日志里有没有 “crawled” 字样,要直接观察 Redis 中的三个关键 key:
-
llen my_spider:start_urls:初始 push 后应 >0,随着 worker 消费逐步减少 -
scard my_spider:dupefilter:数值应持续增长,且各 worker 日志中 “Filtered duplicate request” 出现频率应随总量上升而趋于稳定 -
smembers my_spider:dupefilter(抽样):随机取几个指纹反解,确认确实是不同 URL 的哈希,而非全是一样的错误值(比如全为None表示 fingerprint 生成失败)
真正容易被忽略的是:Redis 的 maxmemory 策略。如果用 allkeys-lru 且内存不足,dupefilter 的 set 可能被误删,导致去重彻底失效 —— 生产环境务必设为 noeviction 并配足内存。










