scrapy-redis的搭建 分布式爬虫 去重
master:
一、spider文件
1.需要更改继承的类
from scrapy_redis.spiders import RedisSpider
2.注释掉start_urls
3.在爬虫目录下新创建一个redis_urls.py文件,放所有的URL到redis数据库的列表中
4.回到爬虫文件中,写一个redis_key = '列表的key'
二.settings.py文件
1 #配置分布式的主要配置选项 2 #1.配置调度器; 3 SCHEDULER = 'scrapy_redis.scheduler.Scheduler' 4 #2.配置去重器 5 DUPEFILTER_CLASS = 'scrapy_redis.dupefilter.RFPDupeFilter' 6 #3.配置调度队列 7 SCHEDULER_QUEUE_CLASS='scrapy_redis.queue.PriorityQueue' 8 #4.配置redis主机名 9 REDIS_HOST = 'localhost' 10 #5.配置redis端口号 11 REDIS_PORT = 6379
三.如果要解决scrapy-redis空跑问题
1.在项目目录下,新建一个extensions.py文件,写如下代码:
1 import logging 2 3 from scrapy import signals 4 from scrapy.exceptions import NotConfigured 5 6 logging = logging.getLogger(__name__) 7 8 9 class RedisSpiderSmartIdleClosedExensions(object): 10 11 def __init__(self, idle_number, crawler): 12 self.crawler = crawler 13 self.idle_number = idle_number 14 self.idle_list = [] 15 self.idle_count = 0 16 17 @classmethod 18 def from_crawler(cls, crawler): 19 # first check if the extension should be enabled and raise 20 21 # NotConfigured otherwise 22 23 if not crawler.settings.getbool('MYEXT_ENABLED'): 24 raise NotConfigured 25 26 if not 'redis_key' in crawler.spidercls.__dict__.keys(): 27 raise NotConfigured('Only supports RedisSpider') 28 29 # get the number of items from settings 30 31 idle_number = crawler.settings.getint('IDLE_NUMBER', 360) 32 33 # instantiate the extension object 34 35 ext = cls(idle_number, crawler) 36 37 # connect the extension object to signals 38 39 crawler.signals.connect(ext.spider_opened, signal=signals.spider_opened) 40 41 crawler.signals.connect(ext.spider_closed, signal=signals.spider_closed) 42 43 crawler.signals.connect(ext.spider_idle, signal=signals.spider_idle) 44 45 return ext 46 47 def spider_opened(self, spider): 48 spider.logger.info("opened spider {}, Allow waiting time:{} second".format(spider.name, self.idle_number * 5)) 49 50 def spider_closed(self, spider): 51 spider.logger.info( 52 "closed spider {}, Waiting time exceeded {} second".format(spider.name, self.idle_number * 5)) 53 54 def spider_idle(self, spider): 55 # 程序启动的时候会调用这个方法一次,之后每隔5秒再请求一次 56 # 当持续半个小时都没有spider.redis_key,就关闭爬虫 57 # 判断是否存在 redis_key 58 if not spider.server.exists(spider.redis_key): 59 self.idle_count += 1 60 else: 61 self.idle_count = 0 62 63 if self.idle_count > self.idle_number: 64 # 执行关闭爬虫操作 65 self.crawler.engine.close_spider(spider, 'Waiting time exceeded')
2.打开settings.py文件中EXTENSIONS的注释,将Telent的注释掉,换上:
'项目名.extensions.RedisSpiderSmartIdleClosedExensions': 500,
3.配置settings.py文件:
# 开启扩展
MYEXT_ENABLED = True
# 每5秒就检测一次,检测10次(50秒),如果url还为空,那么就结束爬虫程序
IDLE_NUMBER = 10
slave配置:
前面都一样
需要删除redis_urls文件
settings.py的配置:
1 #配置分布式的主要配置选项 2 #1.配置调度器; 3 SCHEDULER = 'scrapy_redis.scheduler.Scheduler' 4 #2.配置去重器 5 DUPEFILTER_CLASS = 'scrapy_redis.dupefilter.RFPDupeFilter' 6 #3.配置调度队列 7 SCHEDULER_QUEUE_CLASS='scrapy_redis.queue.PriorityQueue' 8 #4.配置redis主机名 9 REDIS_HOST = 'master的IP' 10 #5.配置redis端口号 11 REDIS_PORT = 6379 12 ITEM_PIPELINES = { 13 'meishi.pipelines.MeishiPipeline': 300, 14 # 'scrapy_redis.pipelines.RedisPipeline': 301 15 }
如果存到master的MongoDB数据库,需要将host改成master的ip,数据库改成master的,集合也改成master的
master端和slave端的代码保持一致(改完master端代码后复制一份当成salve端的代码),slave端需要更改以下:
1. redis_urls.py删掉
2. MongoDB数据库的主机号改为master端的
注意:scrapy-redis存在空跑问题
开始连接:
尝试连接mongo:mongo --host masterIP --port 27017
尝试连接master的redis数据库:redis-cli -h masterIP
master的redis数据库配置文件需要做如下更改:
1.将bind 127.0.0.1 注释掉
2.将protected-mode yes 改为 protected-mode no