Python 分布式爬虫实战:Scrapy-Redis 集群爬虫搭建 + 去重 + 断点续爬
2026/6/6 17:51:53 网站建设 项目流程

前言

单机 Scrapy 爬虫受限于队列、内存无法实现多机器协同抓取,Scrapy-Redis 依托 Redis 实现全局任务队列、分布式去重、断点续爬,多台服务器共享待爬 URL 池与已爬指纹库,是中大型爬虫项目集群标配。本章实现 Redis 键结构配置、爬虫改造、布隆过滤器去重、增量抓取、对接前文代理池 / UA 池 / Cookie 池,落地可直接上线的分布式爬虫工程。

本文所需依赖官方文档超链接:

  1. Scrapy 官方文档
  2. Scrapy-Redis 文档
  3. Redis-Py 官方文档

一、分布式爬虫核心原理

1.1 单机与分布式区别

  1. 原生 Scrapy:爬虫队列存储在内存,单机独立运行,多机任务重复抓取、无法共享任务;
  2. Scrapy-Redis:请求队列存入 Redis List,去重指纹存入 Redis Set / 布隆过滤器,所有爬虫节点统一从 Redis 取任务,新增机器自动分担抓取压力。

1.2 Redis 存储五大核心 Key

表格

Redis Key数据结构作用
spider_name:requestsList分布式待爬任务队列,lpop 出队消费
spider_name:dupefilterSet/BloomFilterURL 指纹库,全局去重
spider_name:itemsList爬虫产出数据队列,可对接管道入库
spider_name:crawl_statsHash爬虫运行统计:抓取量、失败量
spider_name:cookie_poolZSet复用前文分布式 Cookie 池

二、环境依赖安装

bash

运行

pip install scrapy==2.11.2 scrapy-redis==0.7.3 redis==5.0.8

三、步骤 1:settings.py 全局分布式配置

python

运行

# 开启Redis调度器与去重过滤器 SCHEDULER = "scrapy_redis.scheduler.Scheduler" DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter" # 断点续爬:保留Redis队列,爬虫重启不丢失任务 SCHEDULER_PERSIST = True # 爬虫空闲等待时长,空闲超时自动关闭爬虫 SCHEDULER_IDLE_BEFORE_CLOSE = 10 # Redis连接配置 REDIS_HOST = "127.0.0.1" REDIS_PORT = 6379 REDIS_DB = 0 # 远程集群填写REDIS_PASSWORD = "xxx" # 开启Redis Item管道 ITEM_PIPELINES = { 'scrapy_redis.pipelines.RedisPipeline': 300, } # 对接自定义UA中间件、代理中间件(复用前面资源池) DOWNLOADER_MIDDLEWARES = { 'spider.middlewares.RandomUAMiddle': 543, 'spider.middlewares.ProxyMiddleware': 550, }

四、步骤 2:Spider 爬虫改造(RedisSpider 继承分布式基类)

python

运行

from scrapy_redis.spiders import RedisSpider import scrapy class GoodsDistSpider(RedisSpider): name = "goods_dist" # 从Redis读取起始任务键,手动lpush起始url redis_key = "goods_dist:start_urls" # 域名限制 allowed_domains = ["demo-goods.com"] def parse(self, response): # 列表页解析商品详情链接 detail_links = response.xpath("//a[@class='detail']/@href").getall() for link in detail_links: yield scrapy.Request(url=link,callback=self.parse_detail) # 分页逻辑 next_page = response.xpath("//a[text()='下一页']/@href").get() if next_page: yield scrapy.Request(next_page,callback=self.parse) def parse_detail(self,response): item = { "title":response.xpath("//h1/text()").get(), "price":response.xpath("//span[@class='price']/text()").get() } yield item

任务下发命令(redis-cli)

redis

LPUSH goods_dist:start_urls https://demo-goods.com/list?page=1

五、步骤 3:中间件对接代理池 + UA 池(分布式全局资源)

middlewares.py

python

运行

import requests import random PROXY_API = "http://127.0.0.1:5010/get_proxy" UA_API = "http://127.0.0.1:5011/get_ua" class RandomUAMiddle: def process_request(self,request,spider): ua = requests.get(UA_API).json()["ua"] request.headers["User-Agent"] = ua class ProxyMiddleware: def process_request(self,request,spider): proxy_json = requests.get(PROXY_API).json() if proxy_json["code"] ==200: proxy = proxy_json["proxy"] request.meta["proxy"] = f"http://{proxy}" # 代理失效回调 def process_exception(self,request,exception,spider): fail_proxy = request.meta["proxy"].replace("http://","") requests.get(f"http://127.0.0.1:5010/proxy_fail/{fail_proxy}") return request

六、进阶:布隆过滤器优化海量 URL 去重(解决 Set 内存溢出)

原生 Set 存储千万级 URL 占用 Redis 内存过高,替换布隆过滤器:

bash

运行

pip install scrapy-redis-bloomfilter

修改 settings 去重配置:

python

运行

DUPEFILTER_CLASS = "scrapy_redis_bloomfilter.BloomFilter" # 布隆过滤器参数 BLOOMFILTER_HASH_NUMBER = 6 BLOOMFILTER_BIT = 30

七、多机集群部署方案

  1. 一台 Redis 服务作为中心存储,所有机器 Redis 配置指向同一台 RedisIP;
  2. 所有服务器部署同一份爬虫代码,统一执行scrapy crawl goods_dist
  3. 任意机器 redis-cli 下发起始 URL,全集群自动分摊抓取任务。

八、增量爬虫实现(只抓取当日新增数据)

  1. 每日定时脚本 LPUSH 当日列表页 URL 至 redis 起始队列;
  2. 布隆过滤器自动过滤已爬历史 URL,仅新增 URL 进入抓取队列;
  3. 搭配 APScheduler 定时任务,实现全自动每日增量采集。

九、数据落地拓展:Redis Item 转存 MySQL

自定义 Pipeline 替代原生 RedisPipeline,批量入库 MySQL:

python

运行

import pymysql class MysqlPipeline: def open_spider(self,spider): self.conn = pymysql.connect(host="127.0.0.1",user="root",passwd="xxx",db="crawl_db") self.cur = self.conn.cursor() def process_item(self,item,spider): sql = "insert into goods(title,price) values(%s,%s)" self.cur.execute(sql,(item["title"],item["price"])) self.conn.commit() return item

十、故障排查优化表

表格

异常处理方案
多节点重复抓取确认 DUPEFILTER_CLASS 配置生效,Redis 指纹正常写入
代理频繁失效扩充代理池 IP 基数,调高代理可用性校验频次
Redis 队列堆积过载横向新增爬虫节点,拆分任务分批下发
内存持续上涨布隆过滤器替代 Set,关闭无用爬虫统计日志

十一、本章总结

Scrapy-Redis 分布式核心:Redis 全局任务队列 + 分布式去重 + 多机集群消费,工程标准组合:Scrapy-Redis + Redis布隆去重 + 全局代理UA Cookie资源池 + MySQL持久化;单机调试直接本地 Redis,生产集群部署独立 Redis 服务。后续拓展:Scrapy-Redis 分布式爬虫监控面板、Kafka 替代 Redis 做任务队列、Docker 容器化一键部署爬虫集群。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询