爬虫中间件

蜘蛛中间件是一个钩子框架,用于Scrapy的蜘蛛处理机制,您可以在其中插入自定义功能来处理发送到Spiders进行处理的响应,以及处理从蜘蛛生成的请求和项目。

激活一个爬虫中间件

要激活一个爬虫中间件组件,将其添加到 SPIDER_MIDDLEWARES 设置中,这是一个字典,其键是 中间件类的路径,其值是中间件的顺序。

这是一个示例:

SPIDER_MIDDLEWARES = {
    "myproject.middlewares.CustomSpiderMiddleware": 543,
}

SPIDER_MIDDLEWARES 设置与 Scrapy 中定义的 SPIDER_MIDDLEWARES_BASE 设置(且不应被覆盖)合并,然后按顺序排序以获取最终启用的中间件列表:第一个中间件是更接近引擎的,最后一个中间件是更接近爬虫的。换句话说,每个中间件的 process_spider_input() 方法将按中间件顺序递增(100, 200, 300, …)调用,而每个中间件的 process_spider_output() 方法将按递减顺序调用。

要决定为您的中间件分配哪个顺序,请参阅 SPIDER_MIDDLEWARES_BASE 设置,并根据您希望插入中间件的位置选择一个值。顺序确实很重要,因为每个 中间件执行不同的操作,您的中间件可能依赖于某些 先前(或后续)中间件的应用。

如果你想禁用内置的中间件(那些在SPIDER_MIDDLEWARES_BASE中定义并默认启用的中间件),你必须在你的项目SPIDER_MIDDLEWARES设置中定义它,并将其值赋为None。例如,如果你想禁用站点外中间件:

SPIDER_MIDDLEWARES = {
    "scrapy.spidermiddlewares.referer.RefererMiddleware": None,
    "myproject.middlewares.CustomRefererSpiderMiddleware": 700,
}

最后,请记住,某些中间件可能需要通过特定设置来启用。有关更多信息,请参阅每个中间件的文档。

编写你自己的爬虫中间件

每个爬虫中间件都是一个Python类,它定义了以下一个或多个方法。

主要入口点是from_crawler类方法,它接收一个 Crawler实例。Crawler 对象让你可以访问,例如,settings

class scrapy.spidermiddlewares.SpiderMiddleware
process_spider_input(response, spider)

此方法针对通过爬虫中间件并进入爬虫的每个响应调用,以进行处理。

process_spider_input() 应该返回 None 或者抛出一个异常。

如果它返回 None,Scrapy 将继续处理此响应,执行所有其他中间件,直到最终将响应交给蜘蛛进行处理。

如果它引发异常,Scrapy 将不会调用任何其他爬虫中间件的 process_spider_input(),并且如果有错误回调函数,则会调用请求的错误回调函数,否则它将启动 process_spider_exception() 链。错误回调的输出会反向链接到 process_spider_output() 进行处理,或者如果它引发异常,则链接到 process_spider_exception()

Parameters:
  • response (Response 对象) – 正在处理的响应

  • spider (Spider 对象) – 此响应所针对的蜘蛛

process_spider_output(response, result, spider)

此方法在Spider处理完响应后,使用Spider返回的结果调用。

process_spider_output() 必须返回一个可迭代的 Request 对象和 item objects

在版本2.7中更改:此方法可以定义为异步生成器,在这种情况下,result是一个异步可迭代对象

考虑将此方法定义为异步生成器,这将是未来版本Scrapy的要求。然而,如果您计划与他人共享您的爬虫中间件,请考虑将Scrapy 2.7作为您爬虫中间件的最低要求,或者使您的爬虫中间件通用,以便它可以在Scrapy 2.7之前的版本中工作。

Parameters:
  • response (Response 对象) – 由蜘蛛生成的响应的输出

  • 结果 (一个可迭代的 Request 对象和 item objects) – 由爬虫返回的结果

  • spider (Spider 对象) – 正在处理其结果的爬虫

process_spider_output_async(response, result, spider)

新版本2.7中新增。

如果定义了,这个方法必须是一个异步生成器,如果result是一个异步可迭代对象,它将被调用而不是process_spider_output()

process_spider_exception(response, exception, spider)

当蜘蛛或process_spider_output()方法(来自先前的蜘蛛中间件)引发异常时,将调用此方法。

process_spider_exception() 应该返回 None 或者一个可迭代的 Requestitem 对象。

如果它返回None,Scrapy将继续处理此异常,执行任何其他process_spider_exception()在接下来的中间件组件中,直到没有中间件组件剩余并且异常到达引擎(在那里它被记录并丢弃)。

如果它返回一个可迭代对象,process_spider_output() 管道 将启动,从下一个蜘蛛中间件开始,并且不会调用其他 process_spider_exception()

Parameters:
  • response (Response 对象) – 当异常被抛出时正在处理的响应

  • 异常 (Exception 对象) – 引发的异常

  • spider (Spider 对象) – 引发异常的爬虫

process_start_requests(start_requests, spider)

此方法在蜘蛛的起始请求时被调用,其工作方式类似于process_spider_output()方法,不同之处在于它没有关联的响应,并且必须仅返回请求(而不是项目)。

它接收一个可迭代对象(在start_requests参数中),并且必须返回另一个Request对象和/或item objects的可迭代对象。

注意

在您的爬虫中间件中实现此方法时,您应始终返回一个可迭代对象(遵循输入的可迭代对象),并且不要消耗所有start_requests迭代器,因为它可能非常大(甚至无界)并导致内存溢出。Scrapy引擎设计为在有处理能力时拉取起始请求,因此起始请求迭代器可以有效地无限进行,只要存在其他停止爬虫的条件(如时间限制或项目/页面计数)。

Parameters:
  • start_requests (一个可迭代的 Request) – 起始请求

  • spider (Spider 对象) – 起始请求所属的爬虫

from_crawler(cls, crawler)

如果存在,这个类方法被调用来从Crawler创建一个中间件实例。它必须返回一个新的中间件实例。Crawler对象提供了对Scrapy所有核心组件的访问,如设置和信号;这是中间件访问它们并将其功能集成到Scrapy中的一种方式。

Parameters:

爬虫 (Crawler object) – 使用此中间件的爬虫

内置爬虫中间件参考

本页面描述了Scrapy自带的所有爬虫中间件组件。有关如何使用它们以及如何编写自己的爬虫中间件的信息,请参阅爬虫中间件使用指南

有关默认启用的组件列表(及其顺序),请参阅 SPIDER_MIDDLEWARES_BASE 设置。

深度中间件

class scrapy.spidermiddlewares.depth.DepthMiddleware[source]

DepthMiddleware 用于跟踪被爬取站点内每个请求的深度。它的工作原理是,当之前没有设置值时(通常只是第一个请求),设置 request.meta['depth'] = 0,否则将其递增1。

它可以用来限制抓取的最大深度,根据深度控制请求的优先级,以及类似的事情。

DepthMiddleware 可以通过以下设置进行配置(更多信息请参阅设置文档):

  • DEPTH_LIMIT - 允许爬取任何站点的最大深度。如果为零,则不施加限制。

  • DEPTH_STATS_VERBOSE - 是否收集每个深度的请求数量。

  • DEPTH_PRIORITY - 是否根据请求的深度进行优先级排序。

HttpErrorMiddleware

class scrapy.spidermiddlewares.httperror.HttpErrorMiddleware[源代码]

过滤掉不成功(错误)的HTTP响应,这样爬虫就不必处理它们,这(大多数时候)会增加开销,消耗更多资源,并使爬虫逻辑更加复杂。

根据HTTP标准,成功的响应是那些状态码在200-300范围内的。

如果您仍然想处理该范围之外的响应代码,您可以使用 handle_httpstatus_list 蜘蛛属性或 HTTPERROR_ALLOWED_CODES 设置来指定蜘蛛能够处理的响应代码。

例如,如果你希望你的爬虫处理404响应,你可以这样做:

from scrapy.spiders import CrawlSpider


class MySpider(CrawlSpider):
    handle_httpstatus_list = [404]

handle_httpstatus_list 键在 Request.meta 中也可以用于指定每个请求允许的响应代码。如果你想允许请求的任何响应代码,可以将元键 handle_httpstatus_all 设置为 True,或者设置为 False 来禁用 handle_httpstatus_all 键的效果。

请记住,通常处理非200响应是个坏主意,除非你确实知道自己在做什么。

更多信息请参阅:HTTP状态码定义

HttpErrorMiddleware 设置

HTTPERROR_ALLOWED_CODES

默认值:[]

传递此列表中包含的所有非200状态码的响应。

HTTPERROR_ALLOW_ALL

默认值:False

传递所有响应,无论其状态码如何。

RefererMiddleware

class scrapy.spidermiddlewares.referer.RefererMiddleware[源代码]

填充请求 Referer 头,基于生成它的响应的URL。

RefererMiddleware 设置

REFERER_ENABLED

默认值:True

是否启用引用中间件。

REFERRER_POLICY

默认值:'scrapy.spidermiddlewares.referer.DefaultReferrerPolicy'

Referrer Policy 在填充请求“Referer”头时应用的策略。

注意

你也可以为每个请求设置引用策略, 使用特殊的 "referrer_policy" Request.meta 键, 其可接受的值与 REFERRER_POLICY 设置相同。

REFERRER_POLICY 的可接受值
  • 要么是scrapy.spidermiddlewares.referer.ReferrerPolicy子类的路径——自定义策略或内置策略之一(见下面的类),

  • 或一个或多个逗号分隔的标准W3C定义的字符串值,

  • 或特殊的 "scrapy-default"

字符串值

类名(作为字符串)

"scrapy-default" (默认)

scrapy.spidermiddlewares.referer.DefaultReferrerPolicy

“no-referrer”

scrapy.spidermiddlewares.referer.NoReferrerPolicy

“no-referrer-when-downgrade”

scrapy.spidermiddlewares.referer.NoReferrerWhenDowngradePolicy

“same-origin”

scrapy.spidermiddlewares.referer.SameOriginPolicy

“origin”

scrapy.spidermiddlewares.referer.OriginPolicy

“strict-origin”

scrapy.spidermiddlewares.referer.StrictOriginPolicy

“origin-when-cross-origin”

scrapy.spidermiddlewares.referer.OriginWhenCrossOriginPolicy

“strict-origin-when-cross-origin”

scrapy.spidermiddlewares.referer.StrictOriginWhenCrossOriginPolicy

“unsafe-url”

scrapy.spidermiddlewares.referer.UnsafeUrlPolicy

class scrapy.spidermiddlewares.referer.DefaultReferrerPolicy[源代码]

“no-referrer-when-downgrade”的一个变体, 增加了如果父请求使用file://s3://方案时,不发送“Referer”。

警告

Scrapy的默认引用策略——就像“no-referrer-when-downgrade”,W3C推荐的浏览器值——将从任何http(s)://发送一个非空的“Referer”头到任何https:// URL,即使域名不同。

“same-origin” 如果您想删除跨域请求的引用信息,可能是更好的选择。

class scrapy.spidermiddlewares.referer.NoReferrerPolicy[源代码]

https://www.w3.org/TR/referrer-policy/#referrer-policy-no-referrer

最简单的策略是“no-referrer”,它指定了从特定请求客户端向任何来源发出的请求中不发送引用信息。头部将完全省略。

class scrapy.spidermiddlewares.referer.NoReferrerWhenDowngradePolicy[source]

https://www.w3.org/TR/referrer-policy/#referrer-policy-no-referrer-when-downgrade

“no-referrer-when-downgrade”策略将从TLS保护的环境设置对象发送完整URL到可能可信的URL,以及从非TLS保护的客户端发送请求到任何来源。

另一方面,来自受TLS保护的客户端对非潜在可信URL的请求将不包含引用信息。Referer HTTP头将不会被发送。

如果没有指定其他策略,这是用户代理的默认行为。

注意

“no-referrer-when-downgrade”策略是W3C推荐的默认策略,并被主要网络浏览器使用。

然而,这并不是Scrapy的默认引用策略(参见 DefaultReferrerPolicy)。

class scrapy.spidermiddlewares.referer.SameOriginPolicy[source]

https://www.w3.org/TR/referrer-policy/#referrer-policy-same-origin

“同源”策略规定,当从特定请求客户端发出同源请求时,将发送一个完整的URL,作为引用信息。

另一方面,跨域请求将不包含引用信息。Referer HTTP 头将不会被发送。

class scrapy.spidermiddlewares.referer.OriginPolicy[来源]

https://www.w3.org/TR/referrer-policy/#referrer-policy-origin

“origin”策略指定,当从特定请求客户端发出同源请求和跨源请求时,仅发送请求客户端的ASCII序列化源作为引用信息。

class scrapy.spidermiddlewares.referer.StrictOriginPolicy[源代码]

https://www.w3.org/TR/referrer-policy/#referrer-policy-strict-origin

“strict-origin”策略在发出请求时发送请求客户端的ASCII序列化来源: - 从受TLS保护的环境设置对象到可能可信的URL,以及 - 从非TLS保护的环境设置对象到任何来源。

另一方面,来自受TLS保护的请求客户端向非潜在可信URL的请求将不包含引用信息。不会发送Referer HTTP头。

class scrapy.spidermiddlewares.referer.OriginWhenCrossOriginPolicy[source]

https://www.w3.org/TR/referrer-policy/#referrer-policy-origin-when-cross-origin

“origin-when-cross-origin”策略规定,当从特定请求客户端发出同源请求时,会发送完整的URL(经过处理后用作引用者)作为引用者信息;而当从特定请求客户端发出跨源请求时,仅发送请求客户端的ASCII序列化来源作为引用者信息。

class scrapy.spidermiddlewares.referer.StrictOriginWhenCrossOriginPolicy[source]

https://www.w3.org/TR/referrer-policy/#referrer-policy-strict-origin-when-cross-origin

“strict-origin-when-cross-origin”策略规定,当从特定请求客户端发出同源请求时,将发送完整的URL(去除引用部分)作为引用信息,而在发出跨源请求时,仅发送请求客户端的ASCII序列化源:

  • 从一个受TLS保护的环境设置对象到一个潜在可信的URL,以及

  • 从非TLS保护的环境设置对象到任何来源。

另一方面,从受TLS保护的客户端向非潜在可信URL发出的请求将不包含引用信息。不会发送Referer HTTP头。

class scrapy.spidermiddlewares.referer.UnsafeUrlPolicy[source]

https://www.w3.org/TR/referrer-policy/#referrer-policy-unsafe-url

“unsafe-url”策略指定了一个完整的URL,经过处理后用作引用者,会与跨源请求和来自特定请求客户端的同源请求一起发送。

注意:策略的名称并非虚言;它是不安全的。 此策略会将TLS保护的资源的来源和路径泄露给不安全的来源。 请仔细考虑为可能敏感的文档设置此类策略的影响。

警告

不建议使用“unsafe-url”策略。

UrlLengthMiddleware

class scrapy.spidermiddlewares.urllength.UrlLengthMiddleware[源代码]

过滤掉URL长度超过URLLENGTH_LIMIT的请求

UrlLengthMiddleware 可以通过以下设置进行配置(更多信息请参阅设置文档):