scrapy-redis 分布式学习记录
学习了scrapy 爬虫框架 觉得这个框架做数据抓取很好用,但是不支持分布式。网上查了有大牛在它基础上进行改进出了一个scrapy-redis 的框架
在网上找了很多教程,但是都没有说到基于scrapy-redis从 0 搭建分布式 爬虫框架的。
因此我决定自己从 0 开始搭建 并把整个过程记录下来 希望后来的人少走一些弯路(环境是基于Red Hat Enterprise Linux Server release 7.2 (Maipo), redis 版本是 redis-4.0.1 python 版本是2.7)
Master 端的配置以及redis的安装
1. 首先这个scrapy-redis 是基于 redis 数据库来实现的分布式 因此 必须要先安装好 redis
以下 操作 是以root 用户来进行
1.1 创建redis 安装目录
mkdir /usr/local/redis
1.2 切换到redis 目录 并下载 redis
cd redis
1.4 解压 并安装 redis
tar -xf redis-4.0.1.tar.gz
cd redis-4.0.1
make && make install
1.5 修改redis 的配置(修改redis.conf)默认的redis 监听端口是127.0.0.1 改成你本机的ip
1.6 启动redis (启动的信息会输出到 nohup.out 中)
cd src
nohup ./redis-server ../redis.conf &
2. 安装scrapy
pip install scrapy_redis
3. 新建一个项目 scrapy startproject MySpider
出现了错误 AttributeError: 'module' object has no attribute 'OP_NO_TLSv1_1'
原因是 pip 安装时 Twisted默认是安装了最新的 Twisted-17.9.0 把 Twisted 卸载掉 安装一个版本比较低的
3.1 卸载 Twisted
pip uninstall Twisted
3.2 更换其他版本的 Twisted
pip install twisted==15.0.0
3.3 然后再尝试新建项目
scrapy startproject MySpider
3.4 创建好项目之后我需要在spider 目录下面创建一个master.py 这个就是master(负责获取url 并保持到redis的队列中,以供其他的slave 使用)
4. 配置scrapy 当我们建立好项目之后,就需要修改settings.py 文件 在里面添加配置
# redis ip
REDIS_HOST = "192.168.1.52"
# redis 端口
REDIS_PORT = 6379
# 使用redis 存储任务调度
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
# 使用redis 配置去重
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
# ROBOTSTXT_OBEY = False
5. 编写 master demo (这里需要注意,以前是继承自Spider 但是如果是做分布式的话需要继承自RedisSpider)
# coding:utf-8
from scrapy_redis.spiders import RedisSpider
class Master(RedisSpider):
"""
"""
name = 'master'
redis_key = 'master:start_urls'
allowed_domains = ['baidu.com']
def parse(self, response):
print response.body
from scrapy_redis.spiders import RedisSpider
class Master(RedisSpider):
"""
"""
name = 'master'
redis_key = 'master:start_urls'
allowed_domains = ['baidu.com']
def parse(self, response):
print response.body
可以看到我这里并没有写start_urls (start_urls 被保存在redis)这也是和scrapy 不同的地方 里面还写了 redis_key 这个很重要,因为scrapy 就是根据这个key 去 redis 里面查找数据的
6. 去redis 里面往队列里面插入数据
[root@localhost src]# ./redis-cli -h 192.168.1.52 -p 6379
192.168.1.52:6379> lpush master:start_urls https://www.baidu.com/
(integer) 1
192.168.1.52:6379>
7. 然后就可以将master的demo 运行起来了
7.1 切换到项目路径下面,将master 的脚本运行起来,运行起来后它就会去redis 里面找到start_urls 然后请求该url 返回response
cd mySpider/mySpider
scrapy crawl master
7.2 当我们每次将项目停掉时redis 里面的start_urls 就会被清空(现在还不清楚是为什么...估计是以pop的方式从redis 里面拿出来的url)
# 到此 Master 节点的demo 已经可以运行起来了,现在我们需要处理的就是 从master的请求的response 里面 处理数据,并将url 保存至 redis 队列中。然后配置其他节点的scrapy 让其他节点的进程从redis 里面拿出url 进行抓取
配置其他节点
1 其他的节点也需要安装scrapy-redis 不需要安装redis 只需要将setting的配置文件加上一条配置
REDIS_URL = 'redis://192.168.1.52:6379'
以下是 slave 的爬虫文件demo
# coding:utf-8
from scrapy_redis.spiders import RedisSpider
class Slave1(RedisSpider):
"""
"""
name = 'slave1'
# redis_key 必须和 master 一样
redis_key = 'master:start_urls'
allowed_domains = ['baidu.com']
def parse(self, response):
print response.body
from scrapy_redis.spiders import RedisSpider
class Slave1(RedisSpider):
"""
"""
name = 'slave1'
# redis_key 必须和 master 一样
redis_key = 'master:start_urls'
allowed_domains = ['baidu.com']
def parse(self, response):
print response.body
然后就可以运行slave 了,当master 拿到url 保存到redis里面的时候,这里就会自动拿到url 然后你只需要在这里处理数据就可以了