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