基于scrapy-redis两种形式的分布式爬虫
redis分布式部署
1.scrapy框架是否可以自己实现分布式?
- 不可以。原因有二。
其一:因为多台机器上部署的scrapy会各自拥有各自的调度器,这样就使得多台机器无法分配start_urls列表中的url。(多台机器无法共享同一个调度器)
其二:多台机器爬取到的数据无法通过同一个管道对数据进行统一的数据持久出存储。(多台机器无法共享同一个管道)
2.基于scrapy-redis组件的分布式爬虫
- scrapy-redis组件中为我们封装好了可以被多台机器共享的调度器和管道,我们可以直接使用并实现分布式数据爬取。
- 实现方式:
1.基于该组件的RedisSpider类
2.基于该组件的RedisCrawlSpider类
3.分布式实现流程:上述两种不同方式的分布式实现流程是统一的
- 3.1 下载scrapy-redis组件:pip install scrapy-redis
- 3.2 redis配置文件的配置:
3.3 修改爬虫文件中的相关代码:
- 将爬虫类的父类修改成基于RedisSpider或者RedisCrawlSpider。注意:如果原始爬虫文件是基于Spider的,则应该将父类修改成RedisSpider,如果原始爬虫文件是基于CrawlSpider的,则应该将其父类修改成RedisCrawlSpider。
- 注释或者删除start_urls列表,切加入redis_key属性,属性值为scrpy-redis组件中调度器队列的名称
3.4 在配置文件中进行相关配置,开启使用scrapy-redis组件中封装好的管道
3.5 在配置文件中进行相关配置,开启使用scrapy-redis组件中封装好的调度器
3.6 在配置文件中进行爬虫程序链接redis的配置:
3.7 开启redis服务器:redis-server 配置文件
3.8 开启redis客户端:redis-cli
3.9 运行爬虫文件:scrapy runspider SpiderFile
3.10 向调度器队列中扔入一个起始url(在redis客户端中操作):lpush redis_key属性值 起始url
1.基于该组件的RedisSpider类爬虫代码如下
数据:国产器械,数据条数10万条
1 # -*- coding: utf-8 -*- 2 import scrapy 3 from scrapy_redis.spiders import RedisSpider 4 from redisSpiderPro.items import RedisspiderproItem 5 class RedisspidertestSpider(RedisSpider): 6 name = 'redisSpiderTest' 7 # allowed_domains = ['www.xxx.com'] 8 # start_urls = ['http://www.xxx.com/'] 9 10 #调度器队列的名称 11 redis_key='data' 12 url='http://db.pharmcube.com/database/cfda/detail/cfda_cn_instrument/' 13 pageNum=1 14 def parse(self, response): 15 num=response.xpath('/html/body/div/table/tbody/tr[1]/td[2]/text()').extract_first() 16 name=response.xpath('/html/body/div/table/tbody/tr[2]/td[2]/text()').extract_first() 17 18 item=RedisspiderproItem() 19 item['num']=num 20 item['name']=name 21 yield item 22 23 if self.pageNum<=10000: 24 self.pageNum+=1 25 new_url=self.url+str(self.pageNum) 26 yield scrapy.Request(url=new_url,callback=self.parse)
setting配置
1 USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36' 2 3 ROBOTSTXT_OBEY = False 4 5 #管道 6 ITEM_PIPELINES = { 7 'scrapy_redis.pipelines.RedisPipeline': 400 8 } 9 10 # 使用scrapy-redis组件的去重队列 11 DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter" 12 # 使用scrapy-redis组件自己的调度器 13 SCHEDULER = "scrapy_redis.scheduler.Scheduler" 14 # 是否允许暂停 15 SCHEDULER_PERSIST = True 16 17 18 #redis连接数据库的参数 19 REDIS_HOST = '192.168.19.38' 20 REDIS_PORT = 6379 21 #编码格式 22 # REDIS_ENCODING = ‘utf-8’ 23 #用户名密码 24 # REDIS_PARAMS = {‘password’:’123456’}
2.基于该组件的RedisCrawlSpider类爬虫代码如下
数据 抽屉网:爬取段子
爬虫代码:
1 import scrapy 2 from scrapy.linkextractors import LinkExtractor 3 from scrapy.spiders import CrawlSpider, Rule 4 from redisCrawlSpiderPro.items import RediscrawlspiderproItem 5 from scrapy_redis.spiders import RedisCrawlSpider 6 7 class CrawlspiderSpider(RedisCrawlSpider): 8 name = 'CrawlSpider' 9 # allowed_domains = ['www.xxx.com'] 10 # start_urls = ['http://www.xxx.com/'] 11 12 redis_key='data' 13 link=LinkExtractor(allow=r'/r/scoff/hot/\d+') 14 rules = ( 15 Rule(link, callback='parse_item', follow=True), 16 ) 17 18 def parse_item(self, response): 19 div_list=response.xpath('//div[@id="content-list"]/div') 20 for div in div_list: 21 item=RediscrawlspiderproItem() 22 item['title'] = div.xpath('./div[3]/div/a/text()').extract_first() 23 item['author'] = div.xpath('./div[3]/div[2]/a[4]/b/text()').extract_first() 24 yield item