Spider 中间件¶
Spider 中间件是一个框架,它提供了钩子进入 Scrapy 的 Spider 处理机制,您可以在其中插入自定义功能来处理发送到Spider进行处理的响应,以及处理从 Spider 生成的请求和项目。
激活 Spider 中间件¶
要激活 Spider 中间件组件,请将其添加到SPIDER_MIDDLEWARES
设置中,该设置是一个字典,其键是中间件类路径,其值是中间件顺序。
以下是一个示例
SPIDER_MIDDLEWARES = {
"myproject.middlewares.CustomSpiderMiddleware": 543,
}
SPIDER_MIDDLEWARES
设置与 Scrapy 中定义的 SPIDER_MIDDLEWARES_BASE
设置合并,然后按顺序排序以获得最终排序的启用中间件列表:第一个中间件是最靠近引擎的,最后一个是最靠近 Spider 的。换句话说,每个中间件的 process_spider_input()
方法将按中间件顺序递增(100、200、300、…)调用,而每个中间件的 process_spider_output()
方法将按顺序递减调用。
要决定为中间件分配哪个顺序,请查看 SPIDER_MIDDLEWARES_BASE
设置并根据要插入中间件的位置选择一个值。顺序很重要,因为每个中间件执行不同的操作,并且您的中间件可能依赖于某些先前(或后续)中间件的应用。
如果要禁用内置中间件(在 SPIDER_MIDDLEWARES_BASE
中定义并默认启用),则必须在您的项目 SPIDER_MIDDLEWARES
设置中定义它并将 None
作为其值。例如,如果要禁用 off-site 中间件
SPIDER_MIDDLEWARES = {
"scrapy.spidermiddlewares.referer.RefererMiddleware": None,
"myproject.middlewares.CustomRefererSpiderMiddleware": 700,
}
最后,请记住,某些中间件可能需要通过特定设置启用。有关更多信息,请参阅每个中间件文档。
编写自己的 Spider 中间件¶
每个 Spider 中间件都是一个 Python 类,它定义了一个或多个下面定义的方法。
主要入口点是 from_crawler
类方法,它接收一个 Crawler
实例。例如,Crawler
对象使您可以访问 设置。
- class scrapy.spidermiddlewares.SpiderMiddleware¶
- process_spider_input(response, spider)¶
此方法对通过 Spider 中间件并进入 Spider 进行处理的每个响应调用。
process_spider_input()
应返回None
或引发异常。如果它返回
None
,Scrapy 将继续处理此响应,执行所有其他中间件,直到最终将响应交给 Spider 进行处理。如果它引发异常,Scrapy 将不会调用任何其他 Spider 中间件
process_spider_input()
,并将调用请求错误回调(如果有),否则将启动process_spider_exception()
链。错误回调的输出将反向链接到其他方向,以便process_spider_output()
处理它,或者如果它引发异常,则调用process_spider_exception()
。
- process_spider_output(response, result, spider)¶
在 Spider 处理响应后,使用 Spider 返回的结果调用此方法。
process_spider_output()
必须返回一个Request
对象和 项目对象 的可迭代对象。考虑将此方法定义为 异步生成器,这将是 Scrapy 未来版本的要求。但是,如果您计划与其他人共享您的 Spider 中间件,请考虑 强制 Scrapy 2.7 作为 Spider 中间件的最低要求,或者 使您的 Spider 中间件通用,以便它适用于早于 Scrapy 2.7 的 Scrapy 版本。
- 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
或一个Request
或item 对象的可迭代对象。如果它返回
None
,Scrapy 将继续处理此异常,执行后续中间件组件中的任何其他process_spider_exception()
,直到没有剩余的中间件组件,并且异常到达引擎(在引擎中记录并丢弃)。如果它返回一个可迭代对象,则
process_spider_output()
管道从下一个蜘蛛中间件开始启动,并且不会调用其他process_spider_exception()
。
- process_start_requests(start_requests, spider)¶
此方法使用蜘蛛的起始请求调用,其工作方式类似于
process_spider_output()
方法,不同之处在于它没有关联的响应,并且只能返回请求(而不是项目)。它接收一个可迭代对象(在
start_requests
参数中),并且必须返回另一个Request
对象和/或item 对象 的可迭代对象。注意
在蜘蛛中间件中实现此方法时,应始终返回一个可迭代对象(遵循输入对象),并且不要消耗所有
start_requests
迭代器,因为它可能非常大(甚至无限),并导致内存溢出。Scrapy 引擎设计为在有能力处理请求时提取起始请求,因此起始请求迭代器可以有效地无限循环,而存在其他停止蜘蛛的条件(例如时间限制或项目/页面计数)。- 参数:
start_requests (
Request
的可迭代对象) – 起始请求spider (
Spider
对象) – 起始请求所属的蜘蛛
内置蜘蛛中间件参考¶
此页面描述了 Scrapy 附带的所有蜘蛛中间件组件。有关如何使用它们以及如何编写自己的蜘蛛中间件的信息,请参阅蜘蛛中间件使用指南。
有关默认启用的组件(及其顺序)的列表,请参阅SPIDER_MIDDLEWARES_BASE
设置。
DepthMiddleware¶
- class scrapy.spidermiddlewares.depth.DepthMiddleware[source]¶
DepthMiddleware 用于跟踪正在抓取的站点内每个 Request 的深度。它的工作原理是,在之前没有设置值(通常只是第一个 Request)时设置
request.meta['depth'] = 0
,否则将其递增 1。它可以用来限制要抓取的最大深度,根据深度控制 Request 优先级,以及类似的事情。
DepthMiddleware
可以通过以下设置进行配置(有关更多信息,请参阅设置文档)DEPTH_LIMIT
- 允许对任何站点抓取的最大深度。如果为零,则不会施加限制。DEPTH_STATS_VERBOSE
- 是否收集每个深度的请求数量。DEPTH_PRIORITY
- 是否根据深度对请求进行优先级排序。
HttpErrorMiddleware¶
- class scrapy.spidermiddlewares.httperror.HttpErrorMiddleware[source]¶
过滤掉不成功的(错误的)HTTP 响应,以便蜘蛛不必处理它们,这(大多数情况下)会带来开销,消耗更多资源,并使蜘蛛逻辑更加复杂。
根据HTTP 标准,成功的响应是状态代码在 200-300 范围内的响应。
如果您仍然希望处理该范围之外的响应代码,则可以使用 handle_httpstatus_list
蜘蛛属性或HTTPERROR_ALLOWED_CODES
设置指定蜘蛛能够处理哪些响应代码。
例如,如果您希望您的蜘蛛处理 404 响应,您可以这样做
from scrapy.spiders import CrawlSpider
class MySpider(CrawlSpider):
handle_httpstatus_list = [404]
Request.meta
的 handle_httpstatus_list
密钥也可以用来指定每个请求允许哪些响应代码。如果要允许请求的任何响应代码,可以将元数据键 handle_httpstatus_all
设置为 True
,如果要禁用 handle_httpstatus_all
密钥的效果,则将其设置为 False
。
但是,请记住,处理非 200 响应通常不是一个好主意,除非您确实知道自己在做什么。
有关更多信息,请参阅:HTTP 状态代码定义。
HttpErrorMiddleware 设置¶
HTTPERROR_ALLOWED_CODES¶
默认值:[]
传递包含在此列表中的所有非 200 状态代码的响应。
HTTPERROR_ALLOW_ALL¶
默认值:False
传递所有响应,无论其状态代码如何。
RefererMiddleware¶
RefererMiddleware 设置¶
REFERER_ENABLED¶
默认值:True
是否启用 Referer 中间件。
REFERRER_POLICY¶
默认值:'scrapy.spidermiddlewares.referer.DefaultReferrerPolicy'
填充请求“Referer”标头时要应用的Referrer 策略。
注意
您还可以使用特殊的 "referrer_policy"
Request.meta 键(与 REFERRER_POLICY
设置接受的相同值)为每个请求设置 Referrer 策略。
REFERRER_POLICY 接受的值¶
可以是
scrapy.spidermiddlewares.referer.ReferrerPolicy
子类的路径(自定义策略或内置策略之一,请参见下面的类),或者是一个或多个逗号分隔的标准 W3C 定义的字符串值,
或者特殊的
"scrapy-default"
。
- class scrapy.spidermiddlewares.referer.DefaultReferrerPolicy[source]¶
“no-referrer-when-downgrade” 的变体,另外如果父请求使用
file://
或s3://
方案,则不会发送“Referer”。
警告
Scrapy 的默认 Referrer 策略(就像 “no-referrer-when-downgrade”,浏览器推荐的 W3C 值一样)会从任何 http(s)://
发送非空的“Referer”标头到任何 https://
URL,即使域不同。
如果您想删除跨域请求的 Referrer 信息,“same-origin” 可能是更好的选择。
- class scrapy.spidermiddlewares.referer.NoReferrerPolicy[source]¶
https://www.w3.org/TR/referrer-policy/#referrer-policy-no-referrer
最简单的策略是“no-referrer”,它指定不将任何 Referrer 信息与从特定请求客户端到任何来源的请求一起发送。标头将完全省略。
- class scrapy.spidermiddlewares.referer.NoReferrerWhenDowngradePolicy[source]¶
https://www.w3.org/TR/referrer-policy/#referrer-policy-no-referrer-when-downgrade
“no-referrer-when-downgrade” 策略会将完整的 URL 与来自 TLS 保护的环境设置对象的请求发送到可能值得信赖的 URL,以及来自未经 TLS 保护的客户端的请求发送到任何来源。
另一方面,来自 TLS 保护客户端到非可能值得信赖的 URL 的请求将不包含任何 Referrer 信息。不会发送 Referer HTTP 标头。
如果未另行指定策略,这是用户代理的默认行为。
注意
“no-referrer-when-downgrade” 策略是 W3C 推荐的默认策略,并且被主要的网络浏览器使用。
但是,它不是 Scrapy 的默认 Referrer 策略(请参见 DefaultReferrerPolicy
)。
- class scrapy.spidermiddlewares.referer.SameOriginPolicy[source]¶
https://www.w3.org/TR/referrer-policy/#referrer-policy-same-origin
“same-origin” 策略指定当从特定请求客户端发出同源请求时,将完整 URL(已剥离以用作 Referrer)作为 Referrer 信息发送。
另一方面,跨源请求将不包含任何 Referrer 信息。不会发送 Referer HTTP 标头。
- class scrapy.spidermiddlewares.referer.OriginPolicy[source]¶
https://www.w3.org/TR/referrer-policy/#referrer-policy-origin
“origin” 策略指定仅将请求客户端来源的 ASCII 序列化作为 Referrer 信息发送,无论从特定请求客户端发出同源请求还是跨源请求。
- class scrapy.spidermiddlewares.referer.StrictOriginPolicy[source]¶
https://www.w3.org/TR/referrer-policy/#referrer-policy-strict-origin
“strict-origin” 策略在发出请求时发送请求客户端来源的 ASCII 序列化:- 从 TLS 保护的环境设置对象到可能值得信赖的 URL,以及 - 从非 TLS 保护的环境设置对象到任何来源。
另一方面,来自 TLS 保护请求客户端到非可能值得信赖的 URL 的请求将不包含任何 Referrer 信息。不会发送 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(已剥离以用作 Referrer)作为 Referrer 信息发送,并且仅在从特定请求客户端发出跨源请求时,将请求客户端来源的 ASCII 序列化作为 Referrer 信息发送。
- 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(已剥离以用作 Referrer)作为 Referrer 信息发送,并且仅在发出跨源请求时发送请求客户端来源的 ASCII 序列化
从 TLS 保护的环境设置对象到可能值得信赖的 URL,以及
从非 TLS 保护的环境设置对象到任何来源。
另一方面,来自 TLS 保护客户端到非可能值得信赖的 URL 的请求将不包含任何 Referrer 信息。不会发送 Referer HTTP 标头。
- class scrapy.spidermiddlewares.referer.UnsafeUrlPolicy[source]¶
https://www.w3.org/TR/referrer-policy/#referrer-policy-unsafe-url
“unsafe-url” 策略指定将完整 URL(已剥离以用作 Referrer)与从特定请求客户端发出的跨源请求和同源请求一起发送。
注意:策略的名称没有说谎;它是不安全的。此策略会将来自 TLS 保护资源的来源和路径泄漏到不安全的来源。仔细考虑为可能敏感的文档设置此类策略的影响。
警告
不建议使用“unsafe-url”策略。
UrlLengthMiddleware¶
- class scrapy.spidermiddlewares.urllength.UrlLengthMiddleware[source]¶
过滤掉 URL 长度超过 URLLENGTH_LIMIT 的请求。
可以通过以下设置配置
UrlLengthMiddleware
(有关更多信息,请参阅设置文档)URLLENGTH_LIMIT
- 允许抓取的 URL 的最大长度。