调度器
覆盖默认调度器
你可以通过在 SCHEDULER 设置中提供你自定义调度器类的完整 Python 路径来使用它。
最小调度器接口
class scrapy.core.scheduler.BaseSchedulersource
调度器组件负责存储从引擎接收到的请求,并在请求时(也发送给引擎)将其反馈。
这些请求的原始来源是:
- Spider:
start方法、为start_urls属性中的 URL 创建的请求、请求回调 - Spider 中间件:
process_spider_output和process_spider_exception方法 - 下载器中间件:
process_request、process_response和process_exception方法
调度器返回其存储的请求的顺序(通过 next_request 方法)在很大程度上决定了这些请求的下载顺序。请参阅请求顺序。
此类中定义的方法构成了 Scrapy 引擎将与之交互的最小接口。
close(reason: str) -> Deferred[None] | None[source]
当引擎关闭爬虫时调用。它接收抓取完成的原因作为参数,并且对于执行清理代码很有用。
参数:
- reason (
str) – 描述爬虫关闭原因的字符串
abstract enqueue_request(request: Request) -> bool[source]
处理引擎接收到的请求。
如果请求正确存储,返回 True,否则返回 False。
如果为 False,引擎将触发 request_dropped 信号,并且不会在稍后时间再次尝试调度请求。作为参考,当请求被去重过滤器拒绝时,默认的 Scrapy 调度器返回 False。
classmethod from_crawler(crawler: Crawler) -> Self[source]
工厂方法,接收当前的 Crawler 对象作为参数。
abstract has_pending_requests() -> bool[source]
如果调度器有已入队的请求,则为 True,否则为 False。
abstract next_request() -> Request | None[source]
返回要处理的下一个 Request,如果目前没有准备好的请求,则返回 None。
返回 None 意味着在当前 reactor 周期中不会将调度器中的请求发送到下载器。引擎将继续调用 next_request 直到 has_pending_requests 为 False。
open(spider: Spider) -> Deferred[None] | None[source]
当引擎打开爬虫时调用。它接收爬虫实例作为参数,并且对于执行初始化代码很有用。
参数:
- spider (
Spider) – 当前抓取的爬虫对象
默认调度器
class scrapy.core.scheduler.Schedulersource
默认调度器。
请求存储在根据优先级排序的优先级队列(SCHEDULER_PRIORITY_QUEUE)中。
默认情况下,所有请求都使用单个基于内存的优先级队列。当使用 JOBDIR 时,还会创建一个基于磁盘的优先级队列,并且只有不可序列化的请求存储在基于内存的优先级队列中。对于给定的优先级值,内存中的请求优先于磁盘中的请求。
每个优先级队列将请求存储在单独的内部队列中,每个优先级值一个。内存优先级队列使用 SCHEDULER_MEMORY_QUEUE 队列,而磁盘优先级队列使用 SCHEDULER_DISK_QUEUE 队列。当请求具有相同优先级时,内部队列决定请求顺序。启动请求默认存储在单独的内部队列中,并且排序方式不同。
重复请求通过 DUPEFILTER_CLASS 的实例进行过滤。
请求顺序
在默认设置下,挂起的请求存储在 LIFO 队列中(启动请求除外)。因此,抓取以 DFO 顺序发生,这通常是最方便的抓取顺序。但是,你可以强制使用 BFO 或自定义顺序(前几个请求除外)。
启动请求顺序
启动请求按照它们从 start() 中产生时的顺序发送,并且给定相同的优先级,其他请求优先于启动请求。
你可以将 SCHEDULER_START_MEMORY_QUEUE 和 SCHEDULER_START_DISK_QUEUE 设置为 None,以便在顺序和优先级方面与其他请求一样处理启动请求。
以 BFO 顺序抓取
如果你确实想以 BFO 顺序抓取,可以通过设置以下设置来实现:
DEPTH_PRIORITY = 1
SCHEDULER_DISK_QUEUE = "scrapy.squeues.PickleFifoDiskQueue"
SCHEDULER_MEMORY_QUEUE = "scrapy.squeues.FifoMemoryQueue"
以自定义顺序抓取
你可以手动设置请求的 priority 以强制执行特定的请求顺序。
并发影响顺序
当挂起的请求低于 CONCURRENT_REQUESTS、CONCURRENT_REQUESTS_PER_DOMAIN 或 CONCURRENT_REQUESTS_PER_IP 的配置值时,这些请求将并发发送。
因此,抓取的前几个请求可能不会遵循期望的顺序。将这些设置降低到 1 可以强制执行期望的顺序(除了第一个请求),但这会显著减慢整个抓取速度。
__init__(dupefilter: BaseDupeFilter, jobdir: str | None = None, dqclass: type[BaseQueue] | None = None, mqclass: type[BaseQueue] | None = None, logunser: bool = False, stats: StatsCollector | None = None, pqclass: type[ScrapyPriorityQueue] | None = None, crawler: Crawler | None = None)[source]
初始化调度器。
参数:
- dupefilter (
scrapy.dupefilters.BaseDupeFilter实例或类似:实现BaseDupeFilter接口的任何类) – 负责检查和过滤重复请求的对象。默认使用DUPEFILTER_CLASS设置的值。 - jobdir (
str或None) – 用于持久化抓取状态的目录路径。默认使用JOBDIR设置的值。请参阅作业:暂停和恢复抓取。 - dqclass (类) – 用作持久请求队列的类。默认使用
SCHEDULER_DISK_QUEUE设置的值。 - mqclass (类) – 用作非持久请求队列的类。默认使用
SCHEDULER_MEMORY_QUEUE设置的值。 - logunser (
bool) – 一个布尔值,指示是否应记录不可序列化的请求。默认使用SCHEDULER_DEBUG设置的值。 - stats (
scrapy.statscollectors.StatsCollector实例或类似:实现StatsCollector接口的任何类) – 一个统计信息收集器对象,用于记录请求调度过程的统计信息。默认使用STATS_CLASS设置的值。 - pqclass (类) – 用作请求优先级队列的类。默认使用
SCHEDULER_PRIORITY_QUEUE设置的值。 - crawler (
scrapy.crawler.Crawler) – 对应于当前抓取的爬虫对象。
__len__() -> int[source]
返回已入队请求的总量。
close(reason: str) -> Deferred[None] | None[source]
如果存在磁盘队列,则将挂起请求转储到磁盘。返回去重过滤器的 close 方法的结果。
enqueue_request(request: Request) -> bool[source]
除非收到的请求被去重过滤器过滤掉,否则尝试将其推入磁盘队列,如果失败则推入内存队列。
增加相应的统计信息,例如:scheduler/enqueued、scheduler/enqueued/disk、scheduler/enqueued/memory。
如果请求成功存储,则返回 True,否则返回 False。
classmethod from_crawler(crawler: Crawler) -> Self[source]
工厂方法,接收当前的 Crawler 对象作为参数。
has_pending_requests() -> bool[source]
如果调度器有已入队的请求,则为 True,否则为 False。
next_request() -> Request | None[source]
从内存队列中返回一个 Request 对象,如果内存队列为空则回退到磁盘队列。如果没有更多已入队的请求,则返回 None。
增加相应的统计信息,例如:scheduler/dequeued、scheduler/dequeued/disk、scheduler/dequeued/memory。
open(spider: Spider) -> Deferred[None] | None[source]
初始化内存队列。如果 jobdir 属性是有效目录,则初始化磁盘队列。返回去重过滤器的 open 方法的结果。