Scrapy 是 Python 爬虫生态中一款非常实用的框架,只需编写少量组件就能轻松抓取网页数据。然而,当目标页面数量急剧增长时,单台服务器的处理能力就会成为瓶颈——无论是抓取速度还是网络请求并发数都难以满足需求。此时,分布式爬虫的优势便凸显出来,它能有效突破单机限制,大幅提升抓取效率。
Scrapy-Redis 正是基于 Redis 实现的一款分布式爬虫组件。其核心设计非常简洁:利用 Redis 统一管理爬取请求(Requests),既承担存储任务,又负责调度工作;同时,爬取到的 items 也会暂存在 Redis 中供后续处理。简单来说,Scrapy-Redis 重写了 Scrapy 中几个关键模块,使原本只能在单机运行的爬虫能够扩展到多台主机协同工作,从而构建起高效的分布式爬虫体系。

在实际操作中,我们通过 Redis 维护一个 URL 队列。所有爬虫节点都连接到这个 Redis 服务获取 URL,每取走一个链接,Redis 就会将其从队列中删除,确保两个爬虫不会重复处理同一地址。即使在极端情况下同时请求到相同 URL,Redis 在返回结果后还会进行二次去重。这样一来,分布式效果便轻松实现——以一台主机作为 Redis 队列服务器,其他主机专门运行爬虫程序。此外,Scrapy-Redis 会始终保持与 Redis 的连接,即使队列暂时为空,爬虫也会定期刷新请求,一旦有新任务加入,立刻开始抓取。
首先,在主机和从机上分别安装所需的依赖库:
pip3 install requests scrapy scrapy-redis redis
安装 Redis
在主机上部署 Redis 服务:
yum install redis
启动 Redis 服务:
systemctl start redis
查看 Redis 版本信息:
redis-cli --version
设置 Redis 开机自启动:
systemctl enable redis.service
修改 Redis 配置文件 /etc/redis.conf:将保护模式设为 no,并注释掉 bind 字段,从而允许远程访问。同时请注意,阿里云的安全组策略需放行 6379 端口。配置修改后务必重启服务:
systemctl restart redis
接着,在主机和从机上分别创建 Scrapy 爬虫项目:
scrapy startproject myspider
在项目的 spiders 目录下新建 test.py 文件:
引入所需模块
import scrapy
import os
from scrapy_redis.spiders import RedisSpider
定义爬虫类
class Test(RedisSpider):
# 爬虫名称,与命令行运行时保持一致
name = "test"
# Redis 中存储起始 URL 的键
redis_key = 'test:start_urls'
# 请求头
headers = {
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/73.0.3683.86 Chrome/73.0.3683.86 Safari/537.36'
}
def parse(self, response):
print(response.url)
pass
然后修改 settings.py 文件,添加如下配置。其中 Redis 地址即为主机配置好的连接信息:
BOT_NAME = 'myspider'
SPIDER_MODULES = ['myspider.spiders']
NEWSPIDER_MODULE = 'myspider.spiders'
# 设置中文编码
FEED_EXPORT_ENCODING = 'utf-8'
# scrapy-redis 主机地址
REDIS_URL = 'redis://root@39.106.228.179:6379'
# 队列调度器
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
# 不清除缓存,保持持久化
SCHEDULER_PERSIST = True
# 通过 Redis 进行 URL 去重
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
# 不遵守 robots.txt 协议
ROBOTSTXT_OBEY = False
最后,在两台主机上分别启动 Scrapy 爬虫服务。此时服务已成功启动,但 Redis 队列中暂无任务,处于等待状态。登录主机进入 Redis 客户端:
redis-cli
向任务队列中推送 URL:
lpush test:start_urls https://baidu.com
lpush test:start_urls https://chouti.com
你会立即发现,两台服务器上的爬虫分别领取了队列中的任务开始抓取。借助 Redis 独特的队列特性,URL 绝不会被重复抓取,从而保证了分布式爬虫的高效与准确。

爬取任务结束后,可以使用 flushdb 命令清除 Redis 中的地址指纹。这样后续就能重新抓取历史 URL。整个过程清晰明了,分布式爬虫的实现门槛其实远没有想象中那么高。
