scrapy-redis分布式爬虫使用及docker swarm集群部署
成果
实现了用docker swarm 集群部署scrapy-redis分布式漫画爬虫,数据统一存储至mongo。
概述
本文大致分为两部分
- scrapy-redis分布式爬虫使用流程
- 使用docker部署分布式爬虫
部署流程逐渐从手动创建容器到容器编排部署。演变流程大致如下
单机Dockerfile+mongo+redis --> 单机docker-compose up --> 分布式 单机docker-compose +修改源码ip连通容器 --> 分布式 docker swarm 手动create服务 --> 分布式 docker-stack部署服务
文中的爬虫代码,Dockerfile,docker-compose.yml,都可在我的github项目 90漫画爬虫 对照观看。
想要直接尝试以下该分布式爬虫可以复制docker-compose.yml 到服务器,创建一个docker swarm集群 。然后 在该目录运行docker stack deploy -c docker-compose.yml <一个名称>
命令即可。
scrapy-redis分布式爬虫
原生scrapy无法实现分布式爬虫,为了实现分布式爬虫,可以采用scrapy-redis组件。
scrapy-redis组件中为我们封装好了可以被多台机器共享的调度器,我们可以直接使用并实现分布式数据爬取。
使用流程
通过对原生的scrapy代码进行部分修改就可以使用scrapy-redis组件。
-
下载scrapy-redis组件:pip3 install scrapy-redis
-
redis配置文件的配置(使用docker不需配置):注释bind 127.0.0.1,表示可以让其他ip访问redis,
protected-mode no,表示可以让其他ip操作redis。
-
修改爬虫文件中的相关代码:基于Spider的类将父类修改成RedisSpider,基于CrawlSpider的,将其父类修改成RedisCrawlSpider。spider中定义一个redis_key (用于往redis中放入start_urls),示例如下
-
class Crawl90Spider(RedisCrawlSpider): name = 'crawl90' redis_key = 'comicSpider'
-
-
settings修改
-
加入以下代码 # 使用scrapy-redis组件的去重队列 DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter" # 使用scrapy-redis组件自己的调度器 SCHEDULER = "scrapy_redis.scheduler.Scheduler" # 是否允许暂停 SCHEDULER_PERSIST = True # redis编码 REDIS_ENCODING = 'utf-8' # 所使用redis的主机的ip,使用docker compose编排的话可以写成服务名 REDIS_HOST = '106.52.33.199' # redis监听的端口 REDIS_PORT = 21111 # 认证密码 REDIS_PARAMS = { 'password':yourpwd}
-
应用pipeline(可直接用RedisPipeline,我用的是自己写的mongo管道) ITEM_PIPELINES = { 'comics90.pipelines.MongoPipeline': 300, # 'scrapy_redis.pipelines.RedisPipeline': 400 }
-
-
开启爬虫程序
-
打开redis-cli,输入 lpush redis_key值 原生scrapy的start_url值
完成
自定义pipeline
pipeline并不是一定需要用scrapy-redis自带的RedisPipeline,只要我们的pipeline都往同一个数据库存item就可以实现统一存储。
先看看人家的RedisPipeline咋写的,处理item的主要代码为process_item及_process_item。
class RedisPipeline(object):
··· 其他代码 ···
def process_item(self, item, spider):
return deferToThread(self._process_item, item, spider)
def _process_item(self, item, spider):
key = self.item_key(item, spider)
data = self