12.分布式爬虫

 

 

一、介绍

原来单进程爬取: scrapy的Scheduler维护的是本机的任务队列(存放Request对象及其回调函数等信息)+本机的去重队列(存放访问过的ur地址)

分布式爬虫_爬虫

现在分布式爬取: 所以实现分布式爬取的关键就是,找一台专门的主机上运行一个共享的队列比如Redis,然后重写Scrapy的Scheduler,让新的Scheduler到其享队列存取Request,并且去除重复的Request请求,进而实现分布式. 关键:

1、共享队列
2、重写scheduler,让其无论是去重还是任务都去访问共享队列
3、为scheduler定制去重规则(利用redis的集合类型)

分布式爬虫_爬虫_02

二、快速实现分布式流程

1. pip3 install scrapy-redis

2. spider中原来继承scrapy.Spider. 现在继承RedisSpider
	from scrapy_redis.spiders import RedisSpider
	
3. spider中不能写start_urls, 换成redis_key='spider:start_urls'

4. settings中配置redis的连接,默认就是本地连接6379
REDIS_HOST = 'localhost'                            # 主机名
REDIS_PORT = 6379                                   # 端口
REDIS_ENCODING = "utf-8"                            # redis编码类型

# REDIS_URL = 'redis://user:pass@hostname:9001'       # 连接URL(优先于以上配置)
# REDIS_PARAMS  = {}                                  # Redis连接参数
# REDIS_PARAMS['redis_cls'] = 'myproject.RedisClient' # 指定连接Redis的Python模块

# 使用scrapy-redis的去重
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"  

# 使用scrapy-redis的调度器
SCHEDULER = "scrapy_redis.scheduler.Scheduler"  
	
# 持久化配置(可选)	
ITEM_PIPELINES = {
   'scrapy_redis.pipelines.RedisPipeline': 299   
}

5. 让爬虫运行开启分布式爬虫
	1) 终端中开启多个进程执行爬虫程序
	2) 去redis中以spider:start_urls为key, 插入一个起始地址
		redis-cli
		lpush spider:start_urls 

三、scrapy去重原理

对于每一个url的请求,调度器都会根据请求得相关信息加密(request_fingerprint)得到一个指纹信息,并且将指纹信息和set()集合中的指纹信息进行比对,如果set()集合中已经存在这个数据,就不在将这个Request放入队列中。如果set()集合中没有存在这个加密后的数据,就将这个Request对象放入队列中,等待被调度。

分布式爬虫_爬虫_03

分布式爬虫_爬虫_04

更多参考 | 链接

四、scrapy和scrapy-redis有什么区别?为什么选择redis数据库?

1.主要区别

  1. scrapy是一个Python爬虫框架,爬取效率极高,具有高度定制性,但是不支持分布式。
  2. scrapy-redis一套基于redis数据库、运行在scrapy框架之上的组件,可以让scrapy支持分布式策略,Slaver端共享Master端redis数据库里的item队列、请求队列和请求指纹集合。

2.为什么选择redis数据库?

  1. 因为redis支持主从同步,而且数据都是缓存在内存中的,所以基于redis的分布式爬虫,对请求和数据的高频读取效率非常高。

  2. 你用过的爬虫框架或者模块有哪些?谈谈他们的区别或者优缺点 ?

    ​ Python自带:urllib,urllib2

    ​ 第 三 方:requests

    ​ 框 架:Scrapy

  3. urllib和urllib2模块都做与请求URL相关的操作,但他们提供不同的功能。

    urllib2.:urllib2.urlopen可以接受一个Request对象或者url,(在接受Request对象时候,可以设置一个URL headers)

    urllib.urlopen只接收一个url

    urllib 有urlencode,urllib2没有,因此总是urllib,urllib2常会一起使用的原因

3.scrapy框架

  1. scrapy是封装起来的框架,他包含了下载器,解析器,日志及异常处理,基于多线程, twisted的方式处理 。
  2. 对于固定单个网站的爬取开发,有优势,但是对于多网站爬取 100个网站,并发及分布式处理方面,不够灵活,不便调整与括展。
  3. request 是一个HTTP库, 它只是用来,进行请求,对于HTTP请求,他是一个强大的库,下载,解析全部自己处理,灵活性更高,高并发与分布式部署也非常灵活,对于功能可以更好实现.

4.Scrapy优缺点:

1.优点

  • scrapy 是异步的

  • 采取可读性更强的xpath代替正则

  • 强大的统计和log系统

  • 同时在不同的url上爬行

  • 支持shell方式,方便独立调试

  • 写middleware,方便写一些统一的过滤器

  • 通过管道的方式存入数据库

2.缺点:

  • 基于python的爬虫框架,扩展性比较差
  • 基于twisted框架,运行中的exception是不会干掉reactor
  • 并且异步框架出错后是不会停掉其他任务的,数据出错后难以察觉。