Skip to main content

蜘蛛中间件

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

激活蜘蛛中间件

要激活蜘蛛中间件组件,将其添加到 SPIDER_MIDDLEWARES 设置,这是一个dict,其中的键是中间件类路径,它们的值是中间件顺序。

这里有一个例子:

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 = {
    'myproject.middlewares.CustomSpiderMiddleware': 543,
    'scrapy.spidermiddlewares.offsite.OffsiteMiddleware': None,
}

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

编写自己的蜘蛛中间件

每个中间件组件是一个Python类,它定义了一个或多个以下方法:

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

对于通过蜘蛛中间件并进入蜘蛛的每个响应,调用此方法进行处理。

process_spider_input() 应该返回 None 或引发异常。

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

如果它引发异常,Scrapy将不会打扰任何其他蜘蛛中间件 process_spider_input(),并将调用请求errback。 errback的输出被链接回另一个方向,以便 process_spider_output() 处理它,如果 process_spider_exception() 引发异常。

参数:
  • response (Response object) – 正在处理的响应
  • spider (Spider object) – 这个响应所针对的蜘蛛
process_spider_output(response, result, spider)

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

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

参数:
  • response (Response object) – 该响应从蜘蛛生成此输出
  • result (an iterable of Request, dict or Item objects) – 由蜘蛛返回的结果
  • spider (Spider object) – 其结果正在处理的蜘蛛
process_spider_exception(response, exception, spider)

当蜘蛛或 process_spider_input() 方法(来自其他蜘蛛中间件)引发异常时,将调用此方法。

process_spider_exception() 应返回 None 或可迭代的 Response,dict或 Item 对象。

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

如果它返回一个可迭代的 process_spider_output() 管道启动,并且不会调用其他 process_spider_exception()

参数:
  • response (Response object) – 当引发异常时正在处理响应
  • exception (Exception object) – 引发异常
  • spider (Spider object) – 引发异常的蜘蛛
process_start_requests(start_requests, spider)

0.15 新版功能.

此方法使用spider的启动请求调用,并且与 process_spider_output() 方法类似,除了它没有相关的响应,并且必须只返回请求(而不是项目)。

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

注解

当在蜘蛛中间件中实现这个方法时,你应该总是返回一个iterable(跟在输入之后),而不是使用所有的 start_requests 迭代器,因为它可能非常大(甚至是无界的),并导致内存溢出。 Scrapy引擎被设计为在有能力处理它们时提取启动请求,因此,在存在停止蜘蛛的其他条件(如时间限制或项目/页计数)的情况下,启动请求迭代器可以是无穷无尽的。

参数:
  • start_requests (an iterable of Request) – 启动请求
  • spider (Spider object) – 启动请求所属的蜘蛛

内置蜘蛛中间件参考

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

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

深度中间件

class scrapy.spidermiddlewares.depth.DepthMiddleware

DepthMiddleware是一个用于跟踪每个请求在站点内的深度的scrape中间件。它可以用来限制最大深度以刮擦或类似的东西。

DepthMiddleware 可以通过以下设置进行配置(有关详细信息,请参阅设置文档):

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

  • DEPTH_STATS - 是否收集深度统计。

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

HttpErrorMiddleware

class scrapy.spidermiddlewares.httperror.HttpErrorMiddleware

过滤掉不成功的(错误的)HTTP响应,以便蜘蛛程序不必处理它们,这(大部分时间)强加了开销,消耗更多的资源,并使得蜘蛛逻辑更复杂。

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

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

例如,如果你想让蜘蛛处理404回复,你可以这样做:

class MySpider(CrawlSpider):
    handle_httpstatus_list = [404]

Request.metahandle_httpstatus_list 密钥也可以用于指定在每个请求的基础上允许哪个响应代码。如果要允许请求的任何响应代码,您还可以将元键 handle_httpstatus_all 设置为 True

但请记住,处理非200响应通常是个坏主意,除非你真的知道你在做什么。

有关更多信息,请参阅:HTTP Status Code Definitions

HttpErrorMiddleware设置

HTTPERROR_ALLOWED_CODES

默认值:[]

传递此列表中包含非200状态代码的所有回复。

HTTPERROR_ALLOW_ALL

默认值:False

传递所有响应,而不管其状态代码。

离线中间件

class scrapy.spidermiddlewares.offsite.OffsiteMiddleware

过滤出对由蜘蛛网域覆盖的网域以外的网址的请求。

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

当你的蜘蛛返回一个不属于蜘蛛所覆盖的域的请求时,这个中间件会记录一个类似于这个的调试消息:

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 属性集,则非现场中间件将允许请求,即使其域未在允许的域中列出。

Referer中间件

class scrapy.spidermiddlewares.referer.RefererMiddleware

根据生成它的响应的URL填充请求 Referer 头。

Referer中间件设置

REFERER_ENABLED

0.15 新版功能.

默认值:True

是否启用引荐中间件。

UrlLengthMiddleware

class scrapy.spidermiddlewares.urllength.UrlLengthMiddleware

过滤掉长度大于URLLENGTH_LIMIT的网址的请求

UrlLengthMiddleware 可以通过以下设置进行配置(有关详细信息,请参阅设置文档):