前言
在上一篇文章“Scrapy源码分析(二):一个参考Scrapy实现的爬虫框架TinyScrapy”,我们基本明白了引擎是爬虫的新增,它主要通过内部的_next_request作为消费者,种子列表生成器和get_response_callback作为生产者,与调度器进行了方法调用。
我们在前文讲过,调度器在本质上可以把它看为队列,在引擎中也主要是入队列enqueue_request和出队列next_request两种操作。那么这篇文章我们就看看调度器具体是如何实现的。
调度器代码初探
我们找到调度器(Scheduler)的代码位置:
然后先看它对外提供的主要方法:
class Scheduler(object):
def __init__(self, dupefilter, jobdir=None, dqclass=None, mqclass=None,
logunser=False, stats=None, pqclass=None):
"""
实例化
:param dupefilter: 链接去重器
:param jobdir:磁盘队列的工作目录
:param dqclass: 磁盘队列类名
:param mqclass: 内存队列类名
:param logunser: 是否记录日志请求
:param stats:
:param pqclass: 优先队列类名
"""
@classmethod
def from_crawler(cls, crawler):
"""
类方法,按照配置文件settings中的配置项,生成调度器实例。
:param crawler: 爬虫类
:return: 实例化调度器(调用__init__方法)
"""
def has_pending_requests(self):
"""
判断调度器中是否为空
:return: 是否还有链接
"""
def open(self, spider):
"""
实例化内存队列、磁盘队列、链接去重器
:param spider: 自定义爬虫
:return: 链接去重器是否开启成功
"""
def close(self, reason):
"""
关闭磁盘队列
:param reason: 关闭原因
:return: 链接去重器是否关闭成功
"""
def enqueue_request(self, request):
"""
入队列
:param request:请求
:return: True
"""
def next_request(self):
"""
出队列
:return:请求
"""
在这