下载器中间件

下载器中间件是 Scrapy 请求/响应处理中的一个钩子框架。它是一个轻量级、低级别的系统,用于全局修改 Scrapy 的请求和响应。

激活下载器中间件

要激活下载器中间件组件,请将其添加到 DOWNLOADER_MIDDLEWARES 设置中,该设置是一个字典,其键是中间件类路径,值是中间件的顺序。

示例如下

DOWNLOADER_MIDDLEWARES = {
    "myproject.middlewares.CustomDownloaderMiddleware": 543,
}

在 Scrapy 中定义的 DOWNLOADER_MIDDLEWARES 设置与 DOWNLOADER_MIDDLEWARES_BASE 设置(不应被覆盖)合并,然后按顺序排序,以获得启用的中间件的最终排序列表:第一个中间件更接近引擎,最后一个更接近下载器。换句话说,每个中间件的 process_request() 方法将按中间件顺序递增调用(100、200、300……),每个中间件的 process_response() 方法将按递减顺序调用。

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

如果要禁用内置中间件(在 DOWNLOADER_MIDDLEWARES_BASE 中定义并默认启用的中间件),您必须在项目的 DOWNLOADER_MIDDLEWARES 设置中定义它,并将其值指定为 None。例如,如果您想禁用用户代理中间件

DOWNLOADER_MIDDLEWARES = {
    "myproject.middlewares.CustomDownloaderMiddleware": 543,
    "scrapy.downloadermiddlewares.useragent.UserAgentMiddleware": None,
}

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

编写自己的下载器中间件

每个下载器中间件都是一个 组件,它定义了以下一个或多个方法

class scrapy.downloadermiddlewares.DownloaderMiddleware

注意

任何下载器中间件方法都可以定义为协程函数 (async def)。

process_request(request)

此方法针对通过下载中间件的每个请求调用。

process_request() 应该返回 None、返回一个 Response 对象、返回一个 Request 对象,或者抛出 IgnoreRequest 异常。

如果它返回 None,Scrapy 将继续处理此请求,执行所有其他中间件,直到最终调用适当的下载器处理程序执行请求(并下载其响应)。

如果它返回一个 Response 对象,Scrapy 将不会调用 任何 其他的 process_request()process_exception() 方法,也不会调用相应的下载函数;它将返回该响应。已安装中间件的 process_response() 方法始终对每个响应调用。

如果它返回一个 Request 对象,Scrapy 将停止调用 process_request() 方法并重新调度返回的请求。一旦新的返回请求被执行,相应的中间件链将在下载的响应上被调用。

如果它抛出 IgnoreRequest 异常,则将调用已安装下载器中间件的 process_exception() 方法。如果它们都没有处理该异常,则调用请求的 errback 函数 (Request.errback)。如果没有代码处理抛出的异常,它将被忽略且不记录(与其他异常不同)。

参数:

request (Request 对象) – 正在处理的请求

process_response(request, response)

process_response() 应该返回一个 Response 对象、返回一个 Request 对象或抛出 IgnoreRequest 异常。

如果它返回一个 Response(可以是相同的给定响应,也可以是全新的响应),该响应将继续由链中的下一个中间件的 process_response() 方法处理。

如果它返回一个 Request 对象,则中间件链停止,并且返回的请求被重新调度以在将来下载。这与从 process_request() 返回请求的行为相同。

如果它抛出 IgnoreRequest 异常,则调用请求的 errback 函数 (Request.errback)。如果没有代码处理抛出的异常,它将被忽略且不记录(与其他异常不同)。

参数:
  • request (是一个 Request 对象) – 产生响应的请求

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

process_exception(request, exception)

下载处理程序process_request()(来自下载器中间件)抛出异常(包括 IgnoreRequest 异常)时,Scrapy 会调用 process_exception()

process_exception() 应该返回:None、一个 Response 对象,或者一个 Request 对象。

如果它返回 None,Scrapy 将继续处理此异常,执行所有其他已安装中间件的 process_exception() 方法,直到没有中间件留下,并且默认异常处理开始生效。

如果它返回一个 Response 对象,则启动已安装中间件的 process_response() 方法链,Scrapy 将不会调用任何其他中间件的 process_exception() 方法。

如果它返回一个 Request 对象,则返回的请求被重新调度以在将来下载。这会停止中间件 process_exception() 方法的执行,就像返回响应一样。

参数:
  • request (是一个 Request 对象) – 产生异常的请求

  • exception (一个 Exception 对象) – 抛出的异常

内置下载器中间件参考

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

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

CookiesMiddleware

class scrapy.downloadermiddlewares.cookies.CookiesMiddleware[source]

此中间件支持与需要 Cookie 的网站(例如使用会话的网站)配合使用。它会跟踪 Web 服务器发送的 Cookie,并在后续请求(来自该爬虫)中将其发回,就像 Web 浏览器一样。

注意

当非 UTF8 编码的字节序列传递给 Request 时,CookiesMiddleware 将记录警告。请参阅 高级自定义 以自定义日志记录行为。

注意

通过 Cookie 头设置的 Cookie 不被 CookiesMiddleware 考虑。如果需要为请求设置 Cookie,请使用 Request.cookies 参数。这是一个已知的当前限制,正在努力解决。

以下设置可用于配置 Cookie 中间件

COOKIES_ENABLED

默认值:True

是否启用 cookie 中间件。如果禁用,则不会向 Web 服务器发送任何 cookie。

请注意,尽管 COOKIES_ENABLED 设置的值如何,如果 Request.meta['dont_merge_cookies'] 求值为 True,则请求的 cookie 将不会发送到 Web 服务器,并且 Response 中收到的 cookie 将不会与现有 cookie 合并。

有关更详细的信息,请参阅 Request 中的 cookies 参数。

COOKIES_DEBUG

默认值:False

如果启用,Scrapy 将记录请求中发送的所有 cookie(即 Cookie 头)和响应中接收到的所有 cookie(即 Set-Cookie 头)。

以下是启用 COOKIES_DEBUG 后的日志示例

2011-04-06 14:35:10-0300 [scrapy.core.engine] INFO: Spider opened
2011-04-06 14:35:10-0300 [scrapy.downloadermiddlewares.cookies] DEBUG: Sending cookies to: <GET http://www.diningcity.com/netherlands/index.html>
        Cookie: clientlanguage_nl=en_EN
2011-04-06 14:35:14-0300 [scrapy.downloadermiddlewares.cookies] DEBUG: Received cookies from: <200 http://www.diningcity.com/netherlands/index.html>
        Set-Cookie: JSESSIONID=B~FA4DC0C496C8762AE4F1A620EAB34F38; Path=/
        Set-Cookie: ip_isocode=US
        Set-Cookie: clientlanguage_nl=en_EN; Expires=Thu, 07-Apr-2011 21:21:34 GMT; Path=/
2011-04-06 14:49:50-0300 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://www.diningcity.com/netherlands/index.html> (referer: None)
[...]

DefaultHeadersMiddleware

class scrapy.downloadermiddlewares.defaultheaders.DefaultHeadersMiddleware[source]

此中间件设置 DEFAULT_REQUEST_HEADERS 设置中指定的所有默认请求头。

DownloadTimeoutMiddleware

class scrapy.downloadermiddlewares.downloadtimeout.DownloadTimeoutMiddleware[source]

此中间件设置 DOWNLOAD_TIMEOUT 设置中指定的请求下载超时。

注意

您还可以使用 download_timeout Request.meta 键按请求设置下载超时;即使禁用 DownloadTimeoutMiddleware,也支持此功能。

HttpAuthMiddleware

class scrapy.downloadermiddlewares.httpauth.HttpAuthMiddleware[source]

此中间件使用 基本访问认证(又称 HTTP 认证)对请求进行认证。

使用 HTTPAUTH_USERHTTPAUTH_PASSHTTPAUTH_DOMAIN 设置进行配置。您还可以通过 metahttp_userhttp_passhttp_auth_domain 按请求覆盖凭据。

使用设置的示例(例如在 custom_settings 中)

from scrapy.spiders import CrawlSpider


class SomeIntranetSiteSpider(CrawlSpider):
    name = "intranet.example.com"
    custom_settings = {
        "HTTPAUTH_USER": "someuser",
        "HTTPAUTH_PASS": "somepass",
        "HTTPAUTH_DOMAIN": "intranet.example.com",
    }

    # .. rest of the spider code omitted ...

使用每个请求元数据的示例

async def start(self):
    yield Request(
        "https://intranet.example.com/protected/",
        meta={
            "http_user": "someuser",
            "http_pass": "somepass",
            "http_auth_domain": "intranet.example.com",
        },
    )

HTTPAUTH_USER

在 2.17.0 版本中添加。

默认值:""

用于 HTTP 基本认证的用户名,应用于所有 URL 与 HTTPAUTH_DOMAIN 匹配的请求。

HTTPAUTH_PASS

在 2.17.0 版本中添加。

默认值:""

用于 HTTP 基本认证的密码。

HTTPAUTH_DOMAIN

在 2.17.0 版本中添加。

默认值:None

发送 HTTP 基本认证凭据的域名(及其子域名)。设置为 None 可将凭据发送到所有请求,但请注意,这可能会将凭据泄露给不相关的域名。

每当设置 HTTPAUTH_USERHTTPAUTH_PASS 时,都必须明确配置此设置。

另请参阅

跨域凭据泄露

HttpCacheMiddleware

class scrapy.downloadermiddlewares.httpcache.HttpCacheMiddleware[source]

此中间件为所有 HTTP 请求和响应提供低级缓存。它必须与缓存存储后端和缓存策略结合使用。

Scrapy 附带以下 HTTP 缓存存储后端

您可以使用 HTTPCACHE_STORAGE 设置更改 HTTP 缓存存储后端。或者,您也可以 实现自己的存储后端。

Scrapy 附带两种 HTTP 缓存策略

您可以使用 HTTPCACHE_POLICY 设置更改 HTTP 缓存策略。或者,您也可以实现自己的策略。

您还可以通过将 dont_cache meta 键设置为 True 来避免缓存每个策略上的响应。

虚拟策略(默认)

class scrapy.extensions.httpcache.DummyPolicy[source]

此策略对任何 HTTP Cache-Control 指令都没有感知。每个请求及其相应的响应都会被缓存。当再次看到相同的请求时,将直接返回响应,而无需从 Internet 传输任何内容。

虚拟策略对于更快地测试爬虫(无需每次都等待下载)以及在没有 Internet 连接时离线尝试爬虫非常有用。目标是能够“重放”爬虫运行,使其完全像以前一样运行

RFC2616 策略

class scrapy.extensions.httpcache.RFC2616Policy[source]

此策略提供符合 RFC2616 标准的 HTTP 缓存,即具有 HTTP Cache-Control 感知,旨在生产中使用,并在持续运行中避免下载未修改的数据(以节省带宽并加快抓取速度)。

已实现的功能

  • 不尝试存储设置了 no-store 缓存控制指令的响应/请求

  • 即使对于最新响应,如果设置了 no-cache 缓存控制指令,也不从缓存中提供响应

  • max-age 缓存控制指令计算新鲜度寿命

  • Expires 响应头计算新鲜度寿命

  • Last-Modified 响应头计算新鲜度寿命(Firefox 使用的启发式方法)

  • Age 响应头计算当前年龄

  • Date 头计算当前年龄

  • 根据 Last-Modified 响应头重新验证陈旧响应

  • 根据 ETag 响应头重新验证陈旧响应

  • 为任何缺少 Date 头的接收响应设置 Date

  • 支持请求中的 max-stale 缓存控制指令

这允许爬虫配置完整的 RFC2616 缓存策略,但避免按请求进行重新验证,同时仍然符合 HTTP 规范。

示例:

Cache-Control: max-stale=600 添加到请求头中,以接受过期时间不超过 600 秒的响应。

另请参阅:RFC2616, 14.9.3

缺少的功能

文件系统存储后端(默认)

class scrapy.extensions.httpcache.FilesystemCacheStorage[source]

文件系统存储后端可用于 HTTP 缓存中间件。

每个请求/响应对都存储在不同的目录中,包含以下文件

  • request_body - 纯请求体

  • request_headers - 请求头(原始 HTTP 格式)

  • response_body - 纯响应体

  • response_headers - 请求头(原始 HTTP 格式)

  • meta - 此缓存资源的一些元数据,采用 Python repr() 格式(grep 友好格式)

  • pickled_meta - meta 中的相同元数据,但经过 pickle 化以实现更高效的反序列化

目录名由请求指纹(参见 scrapy.utils.request.fingerprint)生成,并使用一层子目录,以避免在同一目录中创建过多文件(这在许多文件系统中效率低下)。示例如下

/path/to/cache/dir/example.com/72/72811f648e718090f041317756c03adb0ada46c7

DBM 存储后端

class scrapy.extensions.httpcache.DbmCacheStorage[source]

HTTP 缓存中间件也提供 DBM 存储后端。

默认情况下,它使用 dbm,但您可以使用 HTTPCACHE_DBM_MODULE 设置更改它。

编写自己的存储后端

您可以通过创建一个定义了下面描述的方法的 Python 类来实现缓存存储后端。

class scrapy.extensions.httpcache.CacheStorage
open_spider(spider)

此方法在爬虫启动抓取后调用。它处理 open_spider 信号。

参数:

spider (Spider 对象) – 已启动的爬虫

close_spider(spider)

此方法在爬虫关闭后调用。它处理 close_spider 信号。

参数:

spider (Spider 对象) – 已关闭的爬虫

retrieve_response(spider, request)

如果响应存在于缓存中则返回响应,否则返回 None

参数:
  • spider (Spider 对象) – 生成请求的爬虫

  • request (Request 对象) – 用于查找缓存响应的请求

store_response(spider, request, response)

将给定响应存储在缓存中。

参数:
  • spider (Spider 对象) – 响应所针对的爬虫

  • request (Request 对象) – 爬虫生成的相应请求

  • response (Response 对象) – 要存储在缓存中的响应

为了使用您的存储后端,请设置

HTTPCache 中间件设置

HttpCacheMiddleware 可以通过以下设置进行配置

HTTPCACHE_ENABLED

默认值:False

是否启用 HTTP 缓存。

HTTPCACHE_EXPIRATION_SECS

默认值:0

缓存请求的过期时间,单位为秒。

早于此时间的缓存请求将被重新下载。如果为零,缓存请求将永不失效。

HTTPCACHE_DIR

默认值:'httpcache'

用于存储(低级)HTTP 缓存的目录。如果为空,HTTP 缓存将禁用。如果给定相对路径,则相对于项目数据目录。有关更多信息,请参阅:Scrapy 项目的默认结构

HTTPCACHE_IGNORE_HTTP_CODES

默认值:[]

不缓存具有这些 HTTP 代码的响应。

HTTPCACHE_IGNORE_MISSING

默认值:False

如果启用,未在缓存中找到的请求将被忽略,而不是下载。

HTTPCACHE_IGNORE_SCHEMES

默认值:['file']

不缓存具有这些 URI 方案的响应。

HTTPCACHE_STORAGE

默认值:'scrapy.extensions.httpcache.FilesystemCacheStorage'

实现缓存存储后端的类。

HTTPCACHE_DBM_MODULE

默认值:'dbm'

DBM 存储后端中使用的数据库模块。此设置特定于 DBM 后端。

HTTPCACHE_POLICY

默认值:'scrapy.extensions.httpcache.DummyPolicy'

实现缓存策略的类。

HTTPCACHE_GZIP

默认值:False

如果启用,将使用 gzip 压缩所有缓存数据。此设置特定于文件系统后端。

HTTPCACHE_ALWAYS_STORE

默认值:False

如果启用,将无条件缓存页面。

爬虫可能希望所有响应都可在缓存中获得,例如将来与 Cache-Control: max-stale 一起使用。DummyPolicy 缓存所有响应但从不重新验证它们,有时需要更细致的策略。

此设置仍然遵守响应中的 Cache-Control: no-store 指令。如果您不希望这样,请从您提供给缓存中间件的响应的 Cache-Control 头中过滤掉 no-store

HTTPCACHE_IGNORE_RESPONSE_CACHE_CONTROLS

默认值:[]

要忽略的响应中的 Cache-Control 指令列表。

网站通常会设置“no-store”、“no-cache”、“must-revalidate”等,但如果爬虫实际遵守这些指令,它们会因为流量而感到不满。这允许选择性地忽略对于正在抓取的网站不重要的 Cache-Control 指令。

我们假设爬虫不会在请求中发出 Cache-Control 指令,除非它确实需要它们,因此请求中的指令不会被过滤。

HttpCompressionMiddleware

class scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware[source]

此中间件允许从网站发送/接收压缩(gzip, deflate)流量。

此中间件还支持解码 brotli 压缩 以及 zstd 压缩 响应,前提是分别安装了 brotlizstandard

HttpCompressionMiddleware 设置

COMPRESSION_ENABLED

默认值:True

是否启用压缩中间件。

HttpProxyMiddleware

class scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware[source]

此中间件通过为 Request 对象设置 proxy 元值,来设置请求使用的 HTTP 代理。

与 Python 标准库模块 urllib.request 类似,它遵循以下环境变量

  • http_proxy

  • https_proxy

  • no_proxy

您还可以将 proxy meta 键按请求设置为诸如 http://some_proxy_server:porthttp://username:password@some_proxy_server:port 的值。请记住,此值将优先于 http_proxy/https_proxy 环境变量,并且还会忽略 no_proxy 环境变量。

注意

此元键的处理需要在 下载处理程序 内部实现,因此不保证所有第三方处理程序都支持它。目前 H2DownloadHandler 不支持它。

注意

代理 URL 通常使用 http:// 方案。更罕见的是,它使用 https:// 方案。虽然两种代理 URL 都可以与 HTTP 和 HTTPS 目标 URL 一起使用,但所有 4 种情况下的网络交换细节都不同,并且给定下载处理程序可能完全或部分不支持 HTTPS 代理。目前,HTTP11DownloadHandler 仅支持用于 HTTP 目标的 HTTPS 代理。

注意

如果下载处理程序支持,您可以使用 SOCKS 代理 URL(例如 socks5://username:password@some_proxy_server:port)。HttpxDownloadHandler 支持 SOCKS 代理,而其他内置处理程序不支持。

HttpProxyMiddleware 设置

HTTPPROXY_ENABLED

默认值:True

是否启用 HttpProxyMiddleware

HTTPPROXY_AUTH_ENCODING

默认值:"latin-1"

HttpProxyMiddleware 上代理认证的默认编码。

OffsiteMiddleware

class scrapy.downloadermiddlewares.offsite.OffsiteMiddleware[source]

2.11.2 版新增。

过滤掉超出爬虫覆盖域名的 URL 请求。

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

当您的爬虫返回一个不属于爬虫覆盖域的请求时,此中间件将记录一个类似于此的调试消息

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

为避免日志中充斥过多噪音,它只会为每个新的被过滤域名打印一条此类消息。因此,例如,如果 offsite.example 的另一个请求被过滤,则不会打印日志消息。但如果 other.example 的请求被过滤,则会打印一条消息(但仅适用于第一个被过滤的请求)。

如果爬虫没有定义 allowed_domains 属性,或者该属性为空,则站外中间件将允许所有请求。

如果请求的 dont_filter 属性设置为 True,或者 Request.meta 中的 allow_offsite 设置为 True,则 OffsiteMiddleware 将允许该请求,即使其域名未列入允许的域名中。

RedirectMiddleware

class scrapy.downloadermiddlewares.redirect.RedirectMiddleware[source]

此中间件根据响应状态处理请求的重定向。

请求经历的 URL(重定向时)可以在 redirect_urls Request.meta 键中找到。

redirect_urls 中每个重定向的原因可以在 redirect_reasons Request.meta 键中找到。例如:[301, 302, 307, 'meta refresh']

原因的格式取决于处理相应重定向的中间件。例如,RedirectMiddleware 以整数形式指示触发的响应状态码,而 MetaRefreshMiddleware 始终使用字符串 'meta refresh' 作为原因。

RedirectMiddleware 可以通过以下设置进行配置(有关更多信息,请参阅设置文档)

如果 Request.meta 中的 dont_redirect 键设置为 True,则此中间件将忽略该请求。

如果您想在爬虫中处理某些重定向状态码,可以在 handle_httpstatus_list 爬虫属性中指定这些状态码。

例如,如果您希望重定向中间件忽略 301 和 302 响应(并将其传递给您的爬虫),您可以这样做

class MySpider(CrawlSpider):
    handle_httpstatus_list = [301, 302]

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

RedirectMiddleware 设置

REDIRECT_ENABLED

默认值:True

是否启用重定向中间件。

REDIRECT_MAX_TIMES

默认值:20

单个请求将遵循的最大重定向次数。如果超过最大重定向次数,请求将被中止并忽略。

MetaRefreshMiddleware

class scrapy.downloadermiddlewares.redirect.MetaRefreshMiddleware[source]

此中间件根据 meta-refresh HTML 标签处理请求的重定向。

MetaRefreshMiddleware 可以通过以下设置进行配置(有关更多信息,请参阅设置文档)

此中间件遵守 REDIRECT_MAX_TIMES 设置,以及 dont_redirectredirect_urlsredirect_reasons 请求元键,如 RedirectMiddleware 中所述。

MetaRefreshMiddleware 设置

METAREFRESH_ENABLED

默认值:True

是否启用 Meta Refresh 中间件。

METAREFRESH_IGNORE_TAGS

默认值:[]

这些标签内的元标签将被忽略。

2.11.2 版中更改: METAREFRESH_IGNORE_TAGS 的默认值从 [] 更改为 ["noscript"]

METAREFRESH_MAXDELAY

默认值:100

遵循重定向的最大 meta-refresh 延迟(秒)。有些网站使用 meta-refresh 重定向到会话过期页面,因此我们将自动重定向限制为最大延迟。

RetryMiddleware

class scrapy.downloadermiddlewares.retry.RetryMiddleware[source]

一个中间件,用于重试可能由连接超时或 HTTP 500 错误等临时问题导致的失败请求。

失败的页面在抓取过程中被收集,并在爬虫完成所有常规(未失败)页面的抓取后,在末尾重新调度。

RetryMiddleware 可以通过以下设置进行配置(有关更多信息,请参阅设置文档)

如果 Request.meta 中的 dont_retry 键设置为 True,则此中间件将忽略该请求。

要从爬虫回调中重试请求,可以使用 get_retry_request() 函数

scrapy.downloadermiddlewares.retry.get_retry_request(request: Request, *, spider: scrapy.Spider, reason: str | Exception | type[Exception] = 'unspecified', max_retry_times: int | None = None, priority_adjust: int | None = None, logger: Logger = <Logger scrapy.downloadermiddlewares.retry (WARNING)>, give_up_log_level: int | str | None = None, stats_base_key: str = 'retry') Request | None[source]

返回一个新的 Request 对象以重试指定的请求,如果指定请求的重试次数已用尽,则返回 None

例如,在 Spider 回调中,您可以如下使用它

def parse(self, response):
    if not response.text:
        new_request_or_none = get_retry_request(
            response.request,
            spider=self,
            reason="empty",
        )
        return new_request_or_none

spider 是请求重试请求的 Spider 实例。它用于访问 设置统计信息,并提供额外的日志记录上下文(参见 logging.debug())。

reason 是一个字符串、一个 Exception 子类或一个 Exception 对象,它指示请求需要重试的原因。它用于命名重试统计信息。

max_retry_times 是一个数字,用于确定 request 可以重试的最大次数。如果未指定或为 None,则该数字从请求的 max_retry_times 元键中读取。如果未定义 max_retry_times 元键或其值为 None,则该数字从 RETRY_TIMES 设置中读取。

priority_adjust 是一个数字,用于确定新请求的优先级相对于 request 如何变化。如果未指定,则该数字从 RETRY_PRIORITY_ADJUST 设置中读取。

logger 是在记录消息时要使用的 logging.Logger 对象

give_up_log_level 是当请求超过重试次数时记录消息所使用的 日志级别。有关详细信息,请参阅 RETRY_GIVE_UP_LOG_LEVEL

2.17.0 版新增: give_up_log_level 参数。

stats_base_key 是一个字符串,用作重试相关作业统计信息的基键

RetryMiddleware 设置

RETRY_ENABLED

默认值:True

是否启用重试中间件。

RETRY_TIMES

默认值:2

除了第一次下载之外,最大重试次数。

最大重试次数也可以通过 Request.metamax_retry_times 属性按请求指定。初始化时,max_retry_times 元键的优先级高于 RETRY_TIMES 设置。

RETRY_HTTP_CODES

默认值:[500, 502, 503, 504, 522, 524, 408, 429]

要重试的 HTTP 响应代码。其他错误(DNS 查找问题、连接丢失等)总是会被重试。

在某些情况下,您可能希望将 400 添加到 RETRY_HTTP_CODES 中,因为它是用于指示服务器过载的常用代码。默认情况下不包含它,因为 HTTP 规范是这样规定的。

RETRY_EXCEPTIONS

默认值

[
    'scrapy.exceptions.CannotResolveHostError',
    'scrapy.exceptions.DownloadConnectionRefusedError',
    'scrapy.exceptions.DownloadFailedError',
    'scrapy.exceptions.DownloadTimeoutError',
    'scrapy.exceptions.ResponseDataLossError',
    'twisted.internet.error.ConnectionDone',
    'twisted.internet.error.ConnectError',
    'twisted.internet.error.ConnectionLost',
    IOError,
    'scrapy.core.downloader.handlers.http11.TunnelError',
]

要重试的异常列表。

每个列表条目可以是异常类型或其导入路径的字符串形式。

当异常类型不在 RETRY_EXCEPTIONS 中,或者请求的最大重试次数已超出时,异常将不会被捕获(参见 RETRY_TIMES)。要了解未捕获异常的传播,请参见 process_exception()

RETRY_GIVE_UP_LOG_LEVEL

在 2.17.0 版本中添加。

默认值: "ERROR"

当请求超出其重试次数时,用于记录消息的日志级别

可以是级别名称(例如 "WARNING")或数字(例如 logging.WARNING30)。

另请参阅:give_up_log_level, get_retry_request()

RETRY_PRIORITY_ADJUST

默认值: -1

调整重试请求相对于原始请求的优先级

  • 正的优先级调整意味着更高的优先级。

  • 负的优先级调整(默认值)意味着更低的优先级。

RobotsTxtMiddleware

class scrapy.downloadermiddlewares.robotstxt.RobotsTxtMiddleware[source]

此中间件会过滤掉被 robots.txt 排除标准禁止的请求。

为确保 Scrapy 遵守 robots.txt,请确保此中间件已启用,并且 ROBOTSTXT_OBEY 设置已启用。

可以使用 ROBOTSTXT_USER_AGENT 设置来指定用于匹配 robots.txt 文件中的用户代理字符串。如果它为 None,则将使用您随请求发送的 User-Agent 头部或 USER_AGENT 设置(按此顺序)来确定在 robots.txt 文件中使用的用户代理。

此中间件必须与 robots.txt 解析器结合使用。

Scrapy 内置支持以下 robots.txt 解析器

您可以使用 ROBOTSTXT_PARSER 设置更改 robots.txt 解析器。或者您也可以实现对新解析器的支持

如果 Request.meta 中的 dont_obey_robotstxt 键设置为 True,则即使 ROBOTSTXT_OBEY 已启用,此中间件也会忽略该请求。

解析器在几个方面有所不同

  • 实现语言

  • 支持的规范

  • 支持通配符匹配

  • 使用基于长度的规则:特别适用于 AllowDisallow 指令,其中基于路径长度的最具体规则优先于不那么具体(较短)的规则

不同解析器的性能比较可在以下链接中找到。

Protego 解析器

基于 Protego

Scrapy 默认使用此解析器。

RobotFileParser

基于 RobotFileParser

它比 Protego 更快,并且与 Scrapy 1.8.0 之前的版本向后兼容。

要使用此解析器,请设置

Robotexclusionrulesparser

基于 Robotexclusionrulesparser

要使用此解析器

  • 通过运行 pip install robotexclusionrulesparser 安装 Robotexclusionrulesparser

  • ROBOTSTXT_PARSER 设置为 scrapy.robotstxt.RerpRobotParser

实现对新解析器的支持

您可以通过继承抽象基类 RobotParser 并实现下面描述的方法,来支持新的 robots.txt 解析器。

class scrapy.robotstxt.RobotParser[source]
abstractmethod allowed(url: str | bytes, user_agent: str | bytes) bool[source]

如果 user_agent 允许抓取 url,则返回 True,否则返回 False

参数:
  • url (strbytes) – 绝对 URL

  • user_agent (strbytes) – 用户代理

abstractmethod classmethod from_crawler(crawler: Crawler, robotstxt_body: bytes) Self[source]

robots.txt 文件的内容解析为字节。这必须是一个类方法。它必须返回解析器后端的新实例。

参数:

DownloaderStats

class scrapy.downloadermiddlewares.stats.DownloaderStats[source]

此中间件存储所有通过它的请求、响应和异常的统计信息。

要使用此中间件,您必须启用 DOWNLOADER_STATS 设置。

UserAgentMiddleware

class scrapy.downloadermiddlewares.useragent.UserAgentMiddleware[source]

设置 User-Agent 头的中间件。

头部值取自 USER_AGENT 设置。