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