分布式爬虫
这里使用上次完成的项目 DushuPro
链接:https://pan.baidu.com/s/1eNIDWgT42iN-8YOBj0IBGA
提取码:akt3
分布式爬虫
1、分布式爬虫系统
当我们的爬取量非常大的时候,用单机爬虫系统无法及时完成任务,此时就需要部署多台主机,来协同工作;多台主机构成一个集群系统就是分布式。
一个分布式爬虫系统中我们需要一台主服务器和若干台分机:
服务器(master端):要求服务性能较高的主机,硬件上必须配置较高,操作系统最好用Linux,服务器端需要部署一个redis服务器
分机端(slaver端):分机端主要完成爬虫任务,一般的计算机就可以,操作系统可以用windows也可Linux,slaver端需要配置爬虫的相关框架和分布式框架(如果没有分布式框架,需要用待来写)
安装爬虫框架:scrapy或者requests,最常用的是基于scrapy
安装分布式框架:scrapy_redis,主要把爬虫的业务转移成分布式
2、分布式爬虫系统的工作原理
2.1分布式爬虫的数据库
在一个基于scrapy_redis组件分布式爬虫中,master端总共有4个数据库
-
<spider.name>:start_urls :起始url,分布式系统的所有的slaver都会从这个数据库中提取起始url。当分布式系统中所有的slaver端都运行起来以后,他们会去竞争这个数据库的所有url,如果竞争到了则开始调度抓取,如果没有竞争到那些slaver端,会不断的监视start_urls和requests这两个数据库。如果这两个数据库有新的url产生,则继续竞争。
-
<spider.name>:requests:用于盛放在抓取的过程中产生的新的url。如果在爬取的过程中增量式爬虫产生了新的url则新的url会被放入到这个数据库中参与调度。所有slaver端的爬虫开启以后不仅仅要从start_urls数据库中提取url,还会从requests这个数据库中提取
-
<spider.name>:items:用于存储爬虫解析以后返回出去的数据;当某个slaver端的爬虫解析完成以后,会通过分布式组件的管道将爬虫返回的数据,迭代到这个数据库中进行存储。
-
<spider.name>:dupefilter:用于去重,如果一个slaver端爬虫获取到了start_urls或者requests中的一个url以后,这个url会从原来的start_urls或者requests中删除掉其他主机就无法在去重复获取,首先会和dupefilter中的url作对比,如果slaver爬虫获取的这个url在dupefilter中则不再发起请求,继续从start_urls(或者requests)提取新的url再做对比;如果新的提取的url不在dupefilter中则会对这个url发起调度与请求,如果请求成功则将这个url放入到dupefilter里面,否则将这个url原路返回。
2.2 分布式爬虫的运行流程
- 1、所有的slaver端开启爬虫(可以通过一个自动化的脚本控制整个系统,也可以自己手动开启),这些爬虫运行起来以后会同时检测master端的start_urls和requests两个数据库中是否有新的url产生
- 2、通过一个服务器脚本向start_urls这个数据库中写入若干个起始url
- 3、所有的slaver端,凡是从start_urls中拿到了起始url的那些爬虫就会开始爬取,没有拿到的继续等待
- 4、当一个slaver端的增量爬虫匹配若干个url以后会把这些url放入到requests数据库中,解析出来的内容会通过分布式爬虫管道写入到items数据库中,然后把请求成功url加入dupefilter去重队列中,如果请求失败这些失败url会被写回requests中
- 5、其它空闲slaver端拿到requests(或者start_urls)中的url以后,首先会查看这些url有没有被去重,如果被去重则不再重复请求,否则就会请求者url,成功了放入去重队列中,失败了就写回requests中;如此循环往复直至整个网站上的所有的符合规则的url都被写入到去重队列,则所有的爬都会进入等待状态
在redis数据库中可以查看三个数据库的信息
3、依赖包安装 pip install scrapy_redis
如果安装失败,换个镜像源
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple/ scrapy_redis
4、在setting文件中修改管道
ITEM_PIPELINES = {
# 'DushuPro.pipelines.DushuproPipeline': 300, # 把原本的管道注释
# 分布式系统的数据不是存储在当前系统中,而是存储在分布式的master端,此时,我们的管道就要改成分布式的管道
'scrapy_redis.pipelines.RedisPipeline':400,
#这个就是分布式系统的管道类,作用是将当前系统管道内的爬虫传到远程的redis服务器中
}
# 我们指定管道以后,,还需要指定管道将返回到哪个redis服务器中
# 远程redis服务程序的ip地址(域名)
REDIS_HOST = ''
REDIS_PORT = 6379
# 如果有密码,需要如下添加
# REDIS_PARAMS = {'password':'123456'}
# 当前系统的调度器是scrapy的调度器,我们需要将其缓存scrapy_redis的分布式调度器
SCHEDULER = 'scrapy_redis.scheduler.Scheduler'
# 调度过程中是否允许暂停
SCHEDULER_PERSIST = True
# 去重组件 (同一个url只允许被一台主机访问)
DUPEFILTER_CLASS = 'scrapy_redis.dupefilter.RFPDupeFilter'
这些组件也可以找到位置,找到site-packages下的scrapy_redis文件夹
5、接下来修改dushu .py文件
5.1 导入分布式爬虫类
from scrapy_redis.spiders import RedisCrawlSpider
5.2 爬虫类继承scrapy_redis组件中的分布式爬虫类
把class中的内容修改 ,现在class继承的是RedisCrawlSpider
注释原本的 start_urls
class DushuSpider(RedisCrawlSpider):
name = 'dushu'
allowed_domains = ['dushu.com']
# start_urls = ['http://dushu.com/book/1002.html']
# 由于分布式爬虫是从远程的redis数据库中获取起始url,所以这个属性就没用了
#redis_key 属性
redis_key = 'dushu:start_urls'
# 分布式爬虫是从远程的redis数据库中的这个key下获取起始url
5.3 连接远程的redis数据库
使用命令
redis-cli -h 远程redis数据库ip
然后ping一下能不能通
将开始爬取的url导入redis数据库
使用命令
lpush dushu:start_urls http://dushu.com/book/1002.html
在pycharm的Terminal终端输入命令开启爬虫
scrapy crawl dushu
可以看到爬虫开始工作
数据存入到redis数据库中
文件链接:https://pan.baidu.com/s/1lzzHgDW3lBqQZFp3V5mIJA
提取码:0wpj