Downloader Middleware

下载器中间件是一个挂钩Scrapy的请求/响应处理的框架. 这是一个轻量级的低级系统,用于全局更改Scrapy的请求和响应.

Activating a downloader middleware

要激活下载程序中间件组件,请将其添加到DOWNLOADER_MIDDLEWARES设置中,该设置是一个dict,其键为中间件类路径,其值为中间件顺序.

这是一个例子:

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

DOWNLOADER_MIDDLEWARES设置合并到DOWNLOADER_MIDDLEWARES_BASE在Scrapy定义的设置(而不是必须被覆盖),然后才能获得启用中间件的最终排序列表进行排序:第一中间件是一个更接近发动机,最后是距离下载器更近. 换句话说,每个中间件的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,
}

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

Writing your own downloader middleware

每个下载器中间件都是一个Python类,该类定义了以下定义的一个或多个方法.

The main entry point is the from_crawler class method, which receives a Crawler instance. The Crawler object gives you access, for example, to the settings.

class scrapy.downloadermiddlewares.DownloaderMiddleware

Note

任何下载器中间件方法也可能返回延迟.

process_request(request, spider)

对于通过下载中间件的每个请求,都会调用此方法.

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 ). 如果没有代码处理引发的异常,则将其忽略并且不记录(与其他异常不同).

Parameters:
  • requestRequest对象)–正在处理的请求
  • 蜘蛛Spider对象)–此请求所针对的蜘蛛
process_response(request, response, spider)

process_response()应该:返回Response对象,返回Request对象或引发IgnoreRequest异常.

如果它返回一个Response (它可以是相同的给定响应,也可以是全新的响应),则该响应将继续使用链中下一个中间件的process_response()进行处理.

如果它返回一个Request对象,则中间件链将暂停,并将返回的请求重新安排为将来下载. 这与从process_request()返回请求的行为相同.

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

Parameters:
  • request (是一个Request对象)–发起响应的请求
  • 响应Response对象)–正在处理的响应
  • 蜘蛛Spider对象)–针对此响应的蜘蛛
process_exception(request, exception, spider)

当下载处理程序或process_request() (来自下载程序中间件)引发异常(包括IgnoreRequest异常)时,Scrapy会调用process_exception() ).

process_exception()应该返回: NoneResponse对象或Request对象.

如果返回None ,则Scrapy将继续处理此异常,执行已安装中间件的任何其他process_exception()方法,直到没有中间件为止,并且默认异常处理开始.

如果返回Response对象,则会启动已安装中间件的process_response()方法链,并且Scrapy不会费心调用中间件的任何其他process_exception()方法.

如果它返回一个Request对象,则将返回的请求重新安排为将来下载. 这将停止执行中间件的process_exception()方法,就像返回响应一样.

Parameters:
  • request (是一个Request对象)–生成异常的请求
  • 异常Exception对象)–引发的异常
  • 蜘蛛Spider对象)–此请求所针对的蜘蛛
from_crawler(cls, crawler)

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

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

Built-in downloader middleware reference

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

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

CookiesMiddleware

class scrapy.downloadermiddlewares.cookies.CookiesMiddleware

使用此中间件,可以处理需要cookie的站点,例如使用会话的站点. 它会跟踪Web服务器发送的cookie,并像网络浏览器一样,将其发送回后续请求(来自该蜘蛛).

以下设置可用于配置cookie中间件:

COOKIES_ENABLED

Default: True

是否启用Cookies中间件. 如果禁用,则不会将cookie发送到Web服务器.

请注意,尽管Request.设置为COOKIES_ENABLEDRequest. meta['dont_merge_cookies']计算为True ,请求的cookie将不会发送到Web服务器,并且在Response收到的cookie将不会与现有的cookie合并.

For more detailed information see the cookies parameter in Request.

COOKIES_DEBUG

Default: 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

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

DownloadTimeoutMiddleware

class scrapy.downloadermiddlewares.downloadtimeout.DownloadTimeoutMiddleware

该中间件为DOWNLOAD_TIMEOUT设置或download_timeout Spider属性中指定的请求设置下载超时.

Note

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

HttpAuthMiddleware

class scrapy.downloadermiddlewares.httpauth.HttpAuthMiddleware

该中间件使用基本访问身份验证 (也称为HTTP身份验证)对从某些蜘蛛生成的所有请求进行身份验证.

要从某些蜘蛛网启用HTTP身份验证,请设置这些http_userhttp_pass属性.

Example:

from scrapy.spiders import CrawlSpider

class SomeIntranetSiteSpider(CrawlSpider):

    http_user = 'someuser'
    http_pass = 'somepass'
    name = 'intranet.example.com'

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

HttpCacheMiddleware

class scrapy.downloadermiddlewares.httpcache.HttpCacheMiddleware

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

Scrapy附带了三个HTTP缓存存储后端:

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

Scrapy附带了两个HTTP缓存策略:

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

您也可以避免使用dont_cache等于True dont_cache元键在每个策略上缓存响应.

Dummy policy (default)

class scrapy.extensions.httpcache.DummyPolicy

该策略不知道任何HTTP Cache-Control指令. 每个请求及其相应的响应都被缓存. 当再次看到相同的请求时,将返回响应,而不会从Internet传输任何内容.

虚拟策略可用于更快地测试蜘蛛(无需每次都等待下载)以及在没有Internet连接时脱机尝试蜘蛛. 目的是能够"重播"与之前完全相同的蜘蛛运行.

RFC2616 policy

class scrapy.extensions.httpcache.RFC2616Policy

该策略提供了一个符合RFC2616的HTTP缓存,即具有HTTP缓存控制意识,旨在用于生产并在连续运行中使用,以避免下载未修改的数据(以节省带宽并加快爬网速度).

实现的是:

  • 不要尝试使用no-store设置缓存控制指令集来存储响应/请求
  • 如果设置了no-cache cache-control指令(即使是新响应),也不要提供来自缓存的响应
  • 根据max-age缓存控制指令计算新鲜度寿命
  • Expires响应标头计算新鲜度寿命
  • 根据Last-Modified响应标头计算新鲜度生命周期(Firefox使用的启发式)
  • Age响应标头计算当前年龄
  • Date标头计算当前年龄
  • 根据Last-Modified响应标头重新验证过时的响应
  • 根据ETag响应标头重新验证过期响应
  • 为任何缺少的响应设置Date标头
  • 在请求中支持max-stale缓存控制指令

这允许蜘蛛配置完整的RFC2616缓存策略,但避免在逐个请求的基础上进行重新验证,同时保持与HTTP规范的一致性.

Example:

Cache-Control: max-stale=600到Request标头,以接受超过其到期时间不超过600秒的响应.

另请参阅:RFC2616、14.9.3

缺什么:

Filesystem storage backend (default)

class scrapy.extensions.httpcache.FilesystemCacheStorage

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

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

  • request_body普通请求正文
  • request_headers请求标头(原始HTTP格式)
  • response_body简单的响应主体
  • response_headers请求标头(原始HTTP格式)
  • meta此缓存资源的一些元数据,采用Python repr()格式(对grep友好的格式)
  • pickled_meta元数据中的meta数据相同,但经过腌制以实现更有效的反序列化

目录名称是由请求指纹(请参见scrapy.utils.request.fingerprint )制成的,并且一级子目录用于避免在同一目录中创建太多文件(在许多文件系统中效率不高). 示例目录可以是:

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

DBM storage backend

class scrapy.extensions.httpcache.DbmCacheStorage

New in version 0.13.

DBM存储后端也可用于HTTP缓存中间件.

默认情况下,它使用anydbm模块,但是您可以使用HTTPCACHE_DBM_MODULE设置对其进行更改.

Writing your own storage backend

您可以通过创建定义以下方法的Python类来实现缓存存储后端.

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

打开蜘蛛进行爬网后,将调用此方法. 它处理open_spider信号.

Parameters: 蜘蛛Spider对象)–已打开的蜘蛛
close_spider(spider)

关闭蜘蛛网后将调用此方法. 它处理close_spider信号.

Parameters: 蜘蛛Spider对象)–已关闭的蜘蛛
retrieve_response(spider, request)

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

Parameters:
  • 蜘蛛Spider对象)–生成请求的蜘蛛
  • requestRequest对象)–查找缓存响应的请求
store_response(spider, request, response)

将给定的响应存储在缓存中.

Parameters:
  • 蜘蛛Spider对象)–预期响应的蜘蛛
  • requestRequest对象)–蜘蛛生成的相应请求
  • 响应Response对象)–响应存储在缓存中

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

HTTPCache middleware settings

可以通过以下设置配置HttpCacheMiddleware

HTTPCACHE_ENABLED

版本0.11中的新功能.

Default: False

是否启用HTTP缓存.

在版本0.11中更改:在版本0.11之前,使用HTTPCACHE_DIR启用缓存.

HTTPCACHE_EXPIRATION_SECS

Default: 0

缓存的请求的到期时间,以秒为单位.

Cached requests older than this time will be re-downloaded. If zero, cached requests will never expire.

在0.11版中进行了更改:在0.11之前,零表示缓存的请求总是过期.

HTTPCACHE_DIR

Default: 'httpcache'

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

HTTPCACHE_IGNORE_HTTP_CODES

版本0.10中的新功能.

Default: []

不要使用这些HTTP代码缓存响应.

HTTPCACHE_IGNORE_MISSING

Default: False

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

HTTPCACHE_IGNORE_SCHEMES

版本0.10中的新功能.

Default: ['file']

不要使用这些URI方案缓存响应.

HTTPCACHE_STORAGE

Default: 'scrapy.extensions.httpcache.FilesystemCacheStorage'

实现缓存存储后端的类.

HTTPCACHE_DBM_MODULE

版本0.13中的新功能.

Default: 'anydbm'

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

HTTPCACHE_POLICY

版本0.18中的新功能.

Default: 'scrapy.extensions.httpcache.DummyPolicy'

实现缓存策略的类.

HTTPCACHE_GZIP

1.0版中的新功能.

Default: False

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

HTTPCACHE_ALWAYS_STORE

1.1版的新功能.

Default: False

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

蜘蛛可能希望所有响应都在缓存中可用,例如,将来与Cache-Control: max-stale使用. DummyPolicy缓存所有响应,但从不重新验证它们,有时需要更细微的策略.

此设置在响应中仍然遵循Cache-Control: no-store指令. 如果您不希望这样做,则在您提供给缓存中间件的响应中,从Cache-Control头中过滤出no-store .

HTTPCACHE_IGNORE_RESPONSE_CACHE_CONTROLS

1.1版的新功能.

Default: []

响应中的Cache-Control指令列表将被忽略.

站点通常设置"不存储","不缓存","必须重新验证"等,但是如果蜘蛛遵守这些指令,可能会对蜘蛛产生的流量感到不满. 这允许有选择地忽略已知对要爬网的站点不重要的Cache-Control指令.

我们假设除非蜘蛛蜘蛛确实需要它们,否则它不会在请求中发出Cache-Control指令,因此不会过滤请求中的指令.

HttpCompressionMiddleware

class scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware

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

如果安装了brotlipy ,此中间件还支持解码brotli压缩的响应.

HttpCompressionMiddleware Settings

COMPRESSION_ENABLED

Default: True

是否启用压缩中间件.

HttpProxyMiddleware

0.8版的新功能.

class scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware

通过设置Request对象的proxy元值,该中间件将HTTP代理设置为用于Request .

像Python标准库模块urlliburllib2一样 ,它遵循以下环境变量:

  • http_proxy
  • https_proxy
  • no_proxy

您还可以将每个请求的元密钥proxy设置为类似http://some_proxy_server:porthttp://username:password@some_proxy_server:port . 请记住,此值将优先于http_proxy / https_proxy环境变量,并且还将忽略no_proxy环境变量.

RedirectMiddleware

class scrapy.downloadermiddlewares.redirect.RedirectMiddleware

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

请求通过的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响应(并将它们传递给您的Spider),则可以执行以下操作:

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

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

RedirectMiddleware settings

REDIRECT_ENABLED

版本0.13中的新功能.

Default: True

是否将启用重定向中间件.

REDIRECT_MAX_TIMES

Default: 20

单个请求将遵循的最大重定向数.

MetaRefreshMiddleware

class scrapy.downloadermiddlewares.redirect.MetaRefreshMiddleware

该中间件基于meta-refresh html标签处理请求的重定向.

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

该中间件遵循REDIRECT_MAX_TIMES设置, dont_redirectredirect_urlsredirect_reasons请求元密钥,如RedirectMiddleware

MetaRefreshMiddleware settings

METAREFRESH_ENABLED

版本0.17中的新功能.

Default: True

是否将启用Meta Refresh中间件.

METAREFRESH_IGNORE_TAGS

Default: ['script', 'noscript']

这些标记中的元标记将被忽略.

METAREFRESH_MAXDELAY

Default: 100

重定向后的最大元刷新延迟(以秒为单位). 一些网站使用元刷新来重定向到会话过期页面,因此我们将自动重定向限制为最大延迟.

RetryMiddleware

class scrapy.downloadermiddlewares.retry.RetryMiddleware

中间件,用于重试失败的请求,这些请求可能是由临时问题(例如连接超时或HTTP 500错误)引起的.

蜘蛛完成对所有常规(非失败)页面的爬网之后,将在抓取过程中收集失败的页面,并在最后进行重新计划.

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

如果Request.meta dont_retry密钥设置为True,则该中间件将忽略该请求.

RetryMiddleware Settings

RETRY_ENABLED

版本0.13中的新功能.

Default: True

是否启用"重试"中间件.

RETRY_TIMES

Default: 2

除了首次下载外,最大重试次数.

还可以使用Request.meta max_retry_times属性为每个请求指定最大重试次数. 初始化后, max_retry_times元键的优先级高于RETRY_TIMES设置.

RETRY_HTTP_CODES

Default: [500, 502, 503, 504, 522, 524, 408, 429]

重试哪个HTTP响应代码. 总是会重试其他错误(DNS查找问题,连接断开等).

在某些情况下,您可能想在RETRY_HTTP_CODES添加400,因为它是用于指示服务器过载的通用代码. 默认情况下不包含它,因为HTTP规范如此.

RobotsTxtMiddleware

class scrapy.downloadermiddlewares.robotstxt.RobotsTxtMiddleware

该中间件会过滤出robots.txt排除标准禁止的请求.

为了确保Scrapy尊重robots.txt,请确保已启用中间件并且已启用ROBOTSTXT_OBEY设置.

ROBOTSTXT_USER_AGENT设置可用于在robots.txt文件中指定用于匹配的用户代理字符串. 如果为None ,则将与请求一起发送的User-Agent标头或USER_AGENT设置( USER_AGENT顺序)将用于确定在robots.txt文件中使用的用户代理.

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

Scrapy随附对以下robots.txt解析器的支持:

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

If Request.meta has dont_obey_robotstxt key set to True the request will be ignored by this middleware even if ROBOTSTXT_OBEY is enabled.

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

  • 实施语言
  • 支持的规格
  • 支持通配符匹配
  • 基于长度的规则的用法:特别是对于AllowDisallow指令,其中基于路径长度的最具体规则胜过较不具体(较短)的规则

以下链接提供了不同解析器的性能比较.

Protego parser

Based on Protego:

Scrapy默认使用此解析器.

RobotFileParser

基于RobotFileParser

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

为了使用此解析器,请设置:

Reppy parser

基于Reppy

本机实现比Protego提供更好的速度.

为了使用此解析器:

Robotexclusionrulesparser

基于Robotexclusionrulesparser

为了使用此解析器:

Implementing support for a new parser

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

class scrapy.robotstxt.RobotParser
allowed(url, user_agent)

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

Parameters:
  • url字符串 )–绝对URL
  • user_agent字符串 )–用户代理
classmethod from_crawler(crawler, robotstxt_body)

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

Parameters:
  • 搜寻器Crawler实例)–发出请求的搜寻器
  • robotstxt_body字节 )– robots.txt文件的内容.

DownloaderStats

class scrapy.downloadermiddlewares.stats.DownloaderStats

中间件,用于存储通过它的所有请求,响应和异常的统计信息.

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

UserAgentMiddleware

class scrapy.downloadermiddlewares.useragent.UserAgentMiddleware

Middleware that allows spiders to override the default user agent.

为了使Spider覆盖默认的用户代理,必须设置其user_agent属性.

AjaxCrawlMiddleware

class scrapy.downloadermiddlewares.ajaxcrawl.AjaxCrawlMiddleware

基于元片段html标签找到" AJAX可抓取"页面变体的中间件. 有关更多信息,请参见https://developers.google.com/webmasters/ajax-crawling/docs/getting-started .

Note

即使没有此中间件,Scrapy也会为'http://example.com/!#foo=bar''http://example.com/!#foo=bar' URL找到" AJAX可抓取"页面. URL不包含'!#'时,必须使用AjaxCrawlMiddleware. 对于"索引"或"主"网站页面通常是这种情况.

AjaxCrawlMiddleware Settings

AJAXCRAWL_ENABLED

0.21版中的新功能.

Default: False

是否将启用AjaxCrawlMiddleware. 您可能需要为广泛的爬网启用它.

HttpProxyMiddleware settings

HTTPPROXY_ENABLED

Default: True

是否启用HttpProxyMiddleware .

HTTPPROXY_AUTH_ENCODING

Default: "latin-1"

HttpProxyMiddleware上代理身份验证的默认编码.