Powered By GitBook
13.6-Spider Middleware的用法
Spider Middleware 是介入到 Scrapy 的 Spider 处理机制的钩子框架。我们首先来看看它的架构,如图 13-1 所示。
当 Downloader 生成 Response 之后,Response 会被发送给 Spider,在发送给 Spider 之前,Response 会首先经过 Spider Middleware 处理,当 Spider 处理生成 Item 和 Request 之后,Item 和 Request 还会经过 Spider Middleware 的处理。
Spider Middleware 有如下三个作用。
    我们可以在 Downloader 生成的 Response 发送给 Spider 之前,也就是在 Response 发送给 Spider 之前对 Response 进行处理。
    我们可以在 Spider 生成的 Request 发送给 Scheduler 之前,也就是在 Request 发送给 Scheduler 之前对 Request 进行处理。
    我们可以在 Spider 生成的 Item 发送给 Item Pipeline 之前,也就是在 Item 发送给 Item Pipeline 之前对 Item 进行处理。

1. 使用说明

需要说明的是,Scrapy 其实已经提供了许多 Spider Middleware,它们被 SPIDER_MIDDLEWARES_BASE 这个变量所定义。
SPIDER_MIDDLEWARES_BASE 变量的内容如下:
1
{
2
'scrapy.spidermiddlewares.httperror.HttpErrorMiddleware': 50,
3
'scrapy.spidermiddlewares.offsite.OffsiteMiddleware': 500,
4
'scrapy.spidermiddlewares.referer.RefererMiddleware': 700,
5
'scrapy.spidermiddlewares.urllength.UrlLengthMiddleware': 800,
6
'scrapy.spidermiddlewares.depth.DepthMiddleware': 900,
7
}
Copied!
和 Downloader Middleware 一样,Spider Middleware 首先加入到 SPIDER_MIDDLEWARES 设置中,该设置会和 Scrapy 中 SPIDER_MIDDLEWARES_BASE 定义的 Spider Middleware 合并。然后根据键值的数字优先级排序,得到一个有序列表。第一个 Middleware 是最靠近引擎的,最后一个 Middleware 是最靠近 Spider 的。

2. 核心方法

Scrapy 内置的 Spider Middleware 为 Scrapy 提供了基础的功能。如果我们想要扩展其功能,只需要实现某几个方法即可。
每个 Spider Middleware 都定义了以下一个或多个方法的类,核心方法有如下 4 个。
    process_spider_input(response, spider)
    process_spider_output(response, result, spider)
    process_spider_exception(response, exception, spider)
    process_start_requests(start_requests, spider)
只需要实现其中一个方法就可以定义一个 Spider Middleware。下面我们来看看这 4 个方法的详细用法。

process_spider_input(response, spider)

当 Response 通过 Spider Middleware 时,该方法被调用,处理该 Response。
方法的参数有两个:
    response,即 Response 对象,即被处理的 Response
    spider,即 Spider 对象,即该 response 对应的 Spider
process_spider_input() 应该返回 None 或者抛出一个异常。
    如果其返回 None ,Scrapy 将会继续处理该 Response,调用所有其他的 Spider Middleware 直到 Spider 处理该 Response。
    如果其抛出一个异常,Scrapy 将不会调用任何其他 Spider Middlewar e 的 process_spider_input() 方法,并调用 Request 的 errback() 方法。 errback 的输出将会以另一个方向被重新输入到中间件中,使用 process_spider_output() 方法来处理,当其抛出异常时则调用 process_spider_exception() 来处理。

process_spider_output(response, result, spider)

当 Spider 处理 Response 返回结果时,该方法被调用。
方法的参数有三个:
    response,即 Response 对象,即生成该输出的 Response
    result,包含 Request 或 Item 对象的可迭代对象,即 Spider 返回的结果
    spider,即 Spider 对象,即其结果对应的 Spider
process_spider_output() 必须返回包含 Request 或 Item 对象的可迭代对象。

process_spider_exception(response, exception, spider)

当 Spider 或 Spider Middleware 的 process_spider_input() 方法抛出异常时, 该方法被调用。
方法的参数有三个:
    response,即 Response 对象,即异常被抛出时被处理的 Response
    exception,即 Exception 对象,被抛出的异常
    spider,即 Spider 对象,即抛出该异常的 Spider
process_spider_exception() 必须要么返回 None , 要么返回一个包含 Response 或 Item 对象的可迭代对象。
    如果其返回 None ,Scrapy 将继续处理该异常,调用其他 Spider Middleware 中的 process_spider_exception() 方法,直到所有 Spider Middleware 都被调用。
    如果其返回一个可迭代对象,则其他 Spider Middleware 的 process_spider_output() 方法被调用, 其他的 process_spider_exception() 将不会被调用。

process_start_requests(start_requests, spider)

该方法以 Spider 启动的 Request 为参数被调用,执行的过程类似于 process_spider_output() ,只不过其没有相关联的 Response 并且必须返回 Request。
方法的参数有两个:
    start_requests,即包含 Request 的可迭代对象,即 Start Requests
    spider,即 Spider 对象,即 Start Requests 所属的 Spider
其必须返回另一个包含 Request 对象的可迭代对象。

3. 结语

本节介绍了 Spider Middleware 的基本原理和自定义 Spider Middleware 的方法。Spider Middleware 使用的频率不如 Downloader Middleware 的高,在必要的情况下它可以用来方便数据的处理。
Last modified 2yr ago