scrapy-redis
scrapy-redis的源码并不多,因为它是利用Redis数据库重新实现了scrapy中的某些组件
对于一个分布式爬虫框架:
1、分配爬取的任务,为每个爬虫分配不重复的爬取任务
2、汇总爬取的数据,将所有爬取到的数据汇总到一个地方
scrapy-redis为多个爬虫分配爬取任务的方式是:让所有爬虫共享一个存在在Redis数据库中的请求队列(替代各个爬虫独立的请求队列),每个爬虫从请求队列中获得请求,下载并解析页面之后,将解析出来的新的请求再次添加到请求队列中,因此每个爬虫既是下载任务的生产者,有是消费者
为了实现多个爬虫的任务的分配,scrapy-redis重新实现了下面的组件:
基于redis的请求队列(优先队列、FIFO、LIFO)
基于redis的请求去重过滤器(过滤掉重复的请求)
基于以上两个组件的调度器
1、调度器的实现
调度器中最核心的两个方法是enqueue_request和next_request,它们分别对应请求的入队和出队操作。spider提交的request对象最终由scrapy引擎用enqueue_request添加到请求队列中,scrapy引擎同时也调用next_request从请求队列中取出请求,送给下载器进行下载。
self.queue和self.df分别是请求队列和去重过滤器对象。在enqueue_request方法中,使用去重过滤器的request_seen方法来判断request是否重复了,也就是request对应的页面是否已经抓取过了,如果用户没有强制忽略过滤,并且request是重复的,就应该抛弃这个request,并且直接返回False,否则就调用self.queue的push方法将request加入到队列中等待被调用,并返回True。在next_request方法中,调用self.queue的pop方法出队一个request并返回
2、请求队列的实现:
基于redis实现的请求队列:
ProorityQueue优先级队列(默认)
FifoQueue先进先出队列
self.server是redis数据库的连接对象,该连接对象是在Scheduler的from_settings方法中创建的,在创建请求对象的时候被传递给请求队列累的构造器
LifoQueue后进先出队列