Spider Middleware

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

Activating a spider middleware

要激活Spider中间件组件,请将其添加到SPIDER_MIDDLEWARES设置中,这是一个dict,其键为中间件类路径,其值为中间件顺序.

这是一个例子:

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

SPIDER_MIDDLEWARES设置与SPIDER_MIDDLEWARES_BASE中定义的SPIDER_MIDDLEWARES设置合并(但并不意味着要覆盖),然后按顺序进行排序,以获取启用的中间件的最终排序列表:第一个中间件是最接近引擎的中间件,最后一个是中间件.靠近蜘蛛一. 换句话说,每个中间件的process_spider_input()方法将以递增的中间件顺序(100、200、300,...)被调用,每个中间件的process_spider_output()方法将以递减顺序被调用.

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

如果要禁用内置中间件(在SPIDER_MIDDLEWARES_BASE定义并默认启用的中间件),则必须在项目SPIDER_MIDDLEWARES设置中对其进行定义,并将其值指定为None . 例如,如果要禁用场外中间件:

SPIDER_MIDDLEWARES = {
    'myproject.middlewares.CustomSpiderMiddleware': 543,
    'scrapy.spidermiddlewares.offsite.OffsiteMiddleware': None,
}

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

Writing your own spider middleware

每个蜘蛛中间件都是一个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() ,如果有请求,它将调用请求errback,否则它将启动process_spider_exception()链. errback的输出在另一个方向上链回,以供process_spider_output()处理,或者如果引发异常,则链接到process_spider_exception() .

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

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

process_spider_output(response, result, spider)

处理完响应后,将使用Spider从返回的结果中调用此方法.

process_spider_output()必须返回Request ,dict或Item对象的可迭代对象.

Parameters
  • response (Response object) – the response which generated this output from the spider

  • 结果 (可迭代的Request ,dict或Item对象)–蜘蛛返回的结果

  • 蜘蛛Spider对象)–正在处理结果的蜘蛛

process_spider_exception(response, exception, spider)

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

process_spider_exception()应该返回None或可迭代的Request ,dict或Item对象.

如果返回None ,则Scrapy将继续处理此异常,在以下中间件组件中执行任何其他process_spider_exception() ,直到不剩下任何中间件组件且异常到达引擎为止(在该处记录并丢弃该异常).

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

Parameters
  • 响应Response对象)–引发异常时正在处理的响应

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

  • 蜘蛛Spider对象)–引发异常的蜘蛛

process_start_requests(start_requests, spider)

0.15版的新功能.

此方法是由Spider的启动请求调用的,并且与process_spider_output()方法类似,不同之处在于它没有关联的响应,并且仅返回请求(不返回项目).

它接收一个可迭代的(在start_requests参数中),并且必须返回另一个可迭代的Request对象.

Note

在您的Spider中间件中实现此方法时,应始终返回一个可迭代(跟随输入一个),并且不消耗所有start_requests迭代器,因为它可能非常大(甚至是无界)并导致内存溢出. Scrapy引擎被设计为在有能力处理启动请求时拉动启动请求,因此启动请求迭代器在存在其他一些条件(例如时间限制或项目/页数)来停止爬网时可能会无限循环.

Parameters
  • start_requests (可迭代的Request )–启动请求

  • 蜘蛛Spider对象)–开始请求所属的蜘蛛

from_crawler(cls, crawler)

如果存在,则调用该类方法以从Crawler创建中间件实例. 它必须返回中间件的新实例. 搜寻器对象提供对所有Scrapy核心组件(如设置和信号)的访问; 它是中间件访问它们并将其功能连接到Scrapy中的一种方式.

Parameters

搜寻器Crawler对象)–使用此中间件的搜寻器

Built-in spider middleware reference

此页面描述了Scrapy随附的所有蜘蛛中间件组件. 有关如何使用它们以及如何编写自己的Spider中间件的信息,请参阅Spider中间件使用指南 .

有关默认情况下启用的组件(及其顺序)的列表,请参见SPIDER_MIDDLEWARES_BASE设置.

DepthMiddleware

class scrapy.spidermiddlewares.depth.DepthMiddleware[source]

DepthMiddleware用于跟踪要抓取的站点内每个请求的深度. 只要先前没有设置任何值(通常只是第一个Request),然后将request.meta['depth'] = 0设置为该值,否则将其递增1.

它可用于限制要刮除的最大深度,根据其深度控制"请求"优先级,诸如此类.

可以通过以下设置来配置DepthMiddleware (有关更多信息,请参见设置文档):

HttpErrorMiddleware

class scrapy.spidermiddlewares.httperror.HttpErrorMiddleware[source]

过滤掉不成功的(错误的)HTTP响应,以便蜘蛛不必处理它们,这(在大多数情况下)会增加开销,消耗更多的资源,并使蜘蛛逻辑更加复杂.

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

If you still want to process response codes outside that range, you can specify which response codes the spider is able to handle using the handle_httpstatus_list spider attribute or HTTPERROR_ALLOWED_CODES setting.

例如,如果您希望蜘蛛处理404响应,则可以执行以下操作:

class MySpider(CrawlSpider):
    handle_httpstatus_list = [404]

Request.metahandle_httpstatus_list键也可以用于指定每个请求允许的响应代码. 如果要允许请求的任何响应代码,也可以将元键handle_httpstatus_all设置为True .

但是请记住,除非您真的知道自己在做什么,否则处理非200个响应通常不是一个好主意.

有关更多信息,请参见: HTTP状态代码定义 .

HttpErrorMiddleware settings

HTTPERROR_ALLOWED_CODES

Default: []

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

HTTPERROR_ALLOW_ALL

Default: False

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

OffsiteMiddleware

class scrapy.spidermiddlewares.offsite.OffsiteMiddleware[source]

过滤掉蜘蛛覆盖的域之外的URL请求.

该中间件过滤掉主机名不在Spider的allowed_domains属性中的每个请求. 也允许列表中任何域的所有子域. 例如,规则www.example.org也将允许bob.www.example.org但不允许www2.example.comexample.com .

当您的Spider返回一个不属于该Spider所覆盖的域的请求时,此中间件将记录类似于以下内容的调试消息:

DEBUG: Filtered offsite request to 'www.othersite.com': <GET http://www.othersite.com/some/page.html>

为避免日志充满太多噪音,它只会为每个过滤的新域打印这些消息之一. 因此,例如,如果对www.othersite.com另一个请求被过滤,则不会打印任何日志消息. 但是,如果对someothersite.com的请求被过滤,则会显示一条消息(但仅针对第一个过滤的请求).

如果蜘蛛程序未定义allowed_domains属性,或者该属性为空,则场外中间件将允许所有请求.

如果请求设置了dont_filter属性,则即使其域未在允许的域中列出,异地中间件也将允许该请求.

RefererMiddleware

class scrapy.spidermiddlewares.referer.RefererMiddleware[source]

根据生成响应的URL填充请求Referer标头.

RefererMiddleware settings

REFERER_ENABLED

0.15版的新功能.

Default: True

是否启用引用中间件.

REFERRER_POLICY

1.4版的新功能.

Default: 'scrapy.spidermiddlewares.referer.DefaultReferrerPolicy'

填充请求" Referer"标头时要应用的Referrer策略 .

Note

You can also set the Referrer Policy per request, using the special "referrer_policy" Request.meta key, with the same acceptable values as for the REFERRER_POLICY setting.

REFERRER_POLICY的可接受值
  • either a path to a scrapy.spidermiddlewares.referer.ReferrerPolicy subclass — a custom policy or one of the built-in ones (see classes below),

  • 或标准的W3C定义的字符串值之一,

  • 或特殊的"scrapy-default" .

字符串值

类名(作为字符串)

"scrapy-default" (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[source]

" no-referrer-when-downgrade"的变体,另外,如果父请求使用file://s3://方案,则不发送" Referer".

Warning

Scrapy的默认引荐来源网址政策(就像" no-referrer-when-downgrade"一样 ,是浏览器的W3C推荐值http(s)://将从任意http(s)://发送到任何https://的非空" Referer"标头URL,即使域不同也是如此.

如果您想删除跨域请求的引荐来源信息,则"相同来源"可能是一个更好的选择.

class scrapy.spidermiddlewares.referer.NoReferrerPolicy[source]

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

最简单的策略是"无引荐来源",它指定不将引引来源信息与从特定请求客户端发出的请求一起发送到任何源. 标头将被完全省略.

class scrapy.spidermiddlewares.referer.NoReferrerWhenDowngradePolicy[source]

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

"降级时不引用"策略将完整的URL以及来自受TLS保护的环境设置对象的请求发送到可能值得信任的URL,并将来自不受TLS保护的客户端的请求发送到任何源.

另一方面,从受TLS保护的客户端到非潜在可信任URL的请求将不包含引荐来源信息. Referer HTTP标头将不会发送.

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

Note

W3C推荐使用" no-referrer-when-grade降级"策略,主要的Web浏览器都使用该策略.

但是,它不是Scrapy的默认引荐来源网址策略(请参见DefaultReferrerPolicy ).

class scrapy.spidermiddlewares.referer.SameOriginPolicy[source]

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

The “same-origin” policy specifies that a full URL, stripped for use as a referrer, is sent as referrer information when making same-origin requests from a particular request client.

另一方面,跨域请求将不包含引荐来源信息. Referer HTTP标头将不会发送.

class scrapy.spidermiddlewares.referer.OriginPolicy[source]

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

"来源"策略指定在发出来自特定请求客户端的相同来源请求和跨来源请求时,仅发送请求客户端来源的ASCII序列化作为引荐来源信息.

class scrapy.spidermiddlewares.referer.StrictOriginPolicy[source]

https://www.w3.org/TR/referrer-policy/#referrer-policy-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

"起源时交叉来源"策略指定,当从特定请求客户端发出同源请求时,剥离的完整URL作为引荐来源网址作为引荐来源信息发送,并且仅将ASCII序列化来源来自特定请求客户端的跨域请求时,请求客户端作为引荐来源信息发送.

class scrapy.spidermiddlewares.referer.StrictOriginWhenCrossOriginPolicy[source]

https://www.w3.org/TR/referrer-policy/#referrer-policy-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保护的资源到不安全源的路径. 仔细考虑为潜在的敏感文档设置此类策略的影响.

Warning

不建议使用"不安全网址"策略.

UrlLengthMiddleware

class scrapy.spidermiddlewares.urllength.UrlLengthMiddleware[source]

过滤出网址长度超过URLLENGTH_LIMIT的请求

可以通过以下设置来配置UrlLengthMiddleware (有关更多信息,请参见设置文档):