下载器中间件(Downloader Middleware)

下载器中间件是介于Scrapy的request/response处理的钩子框架。 是用于全局修改Scrapy request和response的一个轻量、底层的系统。

激活下载器中间件

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

这里是一个例子:

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

DOWNLOADER_MIDDLEWARES 设置会与Scrapy定义的 DOWNLOADER_MIDDLEWARES_BASE 设置合并(但不是覆盖), 而后根据顺序(order)进行排序,最后得到启用中间件的有序列表: 第一个中间件是最靠近引擎的,最后一个中间件是最靠近下载器的。

关于如何分配中间件的顺序请查看 DOWNLOADER_MIDDLEWARES_BASE 设置,而后根据您想要放置中间件的位置选择一个值。 由于每个中间件执行不同的动作,您的中间件可能会依赖于之前(或者之后)执行的中间件,因此顺序是很重要的。

如果您想禁止内置的(在 DOWNLOADER_MIDDLEWARES_BASE 中设置并默认启用的)中间件, 您必须在项目的 DOWNLOADER_MIDDLEWARES 设置中定义该中间件,并将其值赋为 None 例如,如果您想要关闭user-agent中间件:

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

最后,请注意,有些中间件需要通过特定的设置来启用。 更多内容请查看相关中间件文档。

编写你自己的下载器中间件

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

class scrapy.downloadermiddlewares.DownloaderMiddleware

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

process_request(request, spider)

当每个request通过下载中间件时,该方法被调用。

process_request()应该:返回None、返回一个Response对象、返回一个Request对象或引发一个IgnoreRequest

如果其返回 None ,Scrapy将继续处理该request,执行其他的中间件的相应方法,直到合适的下载器处理函数(download handler)被调用, 该request被执行(其response被下载)。

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

如果其返回 Request 对象,Scrapy则停止调用 process_request方法并重新调度返回的request。 当新返回的request被执行后, 相应地中间件链将会根据下载的response被调用。

如果它引发一个IgnoreRequest异常,则已安装的下载器中间件的process_exception()方法会被调用。 如果没有任何一个方法处理该异常, 则request的errback(Request.errback)方法会被调用。 如果没有代码处理抛出的异常, 则该异常被忽略且不记录(不同于其他异常那样)。

Parameters:
  • request (Request 对象) – 处理的request
  • spider (Spider object) – the spider for which this request is intended
process_response(request, response, spider)

process_response()应该:返回一个Response对象,返回一个Request对象,或者引发一个IgnoreRequest异常。

如果其返回一个 Response(可以与传入的response相同,也可以是全新的对象), 该response会被在链中的其他中间件的process_response()方法处理。

如果其返回一个 Request 对象,则中间件链停止, 返回的request会被重新调度下载。 处理类似于process_request()返回request所做的那样。

如果其抛出一个 IgnoreRequest 异常,则调用request的errback(Request.errback)。 如果没有代码处理抛出的异常,则该异常被忽略且不记录(不同于其他异常那样)。

Parameters:
  • request (是 Request 对象) – 产生异常的request
  • response (Response 对象) – 被处理的response
  • spider (Spider object) – the spider for which this response is intended
process_exception(request, exception, spider)

当下载处理器或process_request() (从下载中间件)抛出异常(包括IgnoreRequest异常)时, Scrapy调用process_exception()

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

如果其返回None,Scrapy将会继续处理该异常,接着调用已安装的其他中间件的process_exception() 方法,直到所有中间件都被调用完毕,则调用默认的异常处理。

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

如果其返回一个 Request 对象, 则返回的request将会被重新调用下载。 这将停止中间件的process_exception()方法执行,就如返回一个response的那样。

Parameters:
  • request (Request 对象) – response所对应的request
  • exception (Exception 对象) – 抛出的异常
  • spider (Spider object) – the spider for which this request is intended

内置下载中间件参考

本页面介绍了Scrapy自带的所有下载中间件。 关于如何使用及编写您自己的中间件,请参考 downloader middleware usage guide.

关于默认启用的中间件列表(及其顺序)请参考 DOWNLOADER_MIDDLEWARES_BASE 设置。

CookiesMiddleware

class scrapy.downloadermiddlewares.cookies.CookiesMiddleware

该中间件使得爬取需要cookie(例如使用session)的网站成为了可能。 其追踪了web server发送的cookie,并在之后的request中发送回去, 就如浏览器所做的那样。

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

COOKIES_ENABLED

默认: True

是否启用cookies middleware。 如果关闭,cookies将不会发送给web server。

COOKIES_DEBUG

默认: False

如果启用,Scrapy将记录所有在request中发送的cookie(即Cookie头)和所有在response中收到的cookie(即Set-Cookie头)。

下边是启用 COOKIES_DEBUG 的记录的样例:

2011-04-06 14:35:10-0300 [scrapy] INFO: Spider opened
2011-04-06 14:35:10-0300 [scrapy] 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] 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] DEBUG: Crawled (200) <GET http://www.diningcity.com/netherlands/index.html> (referer: None)
[...]

DefaultHeadersMiddleware

class scrapy.downloadermiddlewares.defaultheaders.DefaultHeadersMiddleware

该中间件设置 DEFAULT_REQUEST_HEADERS 指定的默认request header。

DownloadTimeoutMiddleware

class scrapy.downloadermiddlewares.downloadtimeout.DownloadTimeoutMiddleware

该中间件设置 DOWNLOAD_TIMEOUT 或 spider的 download_timeout 属性指定的request下载超时时间.

Note

您也可以使用 download_timeout Request.meta key 来对每个请求设置下载超时时间. 这种方式在 DownloadTimeoutMiddleware 被关闭时仍然有效.

HttpAuthMiddleware

class scrapy.downloadermiddlewares.httpauth.HttpAuthMiddleware

该中间件完成某些使用Basic access authentication (或者叫HTTP认证)的spider生成的请求的认证过程(即HTTP auth)。

在spider中启用HTTP认证,请设置spider的 http_userhttp_pass 属性。

样例:

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 request及response提供了底层(low-level)缓存支持。 其由cache存储后端及cache策略组成。

Scrapy提供了两种HTTP缓存存储后端:

您可以使用 HTTPCACHE_STORAGE 设定来修改HTTP缓存存储后端。 您也可以实现您自己的存储后端。

Scrapy提供了两种了缓存策略:

您可以使用 HTTPCACHE_POLICY 设定来修改HTTP缓存存储后端。 您也可以实现您自己的存储策略。

You can also avoid caching a response on every policy using dont_cache meta key equals True.

Dummy policy (default)

该策略不考虑任何HTTP Cache-Control指令。 每个request及其对应的response都被缓存。 当相同的request发生时,其不发送任何数据,直接返回response。

Dummpy策略对于测试spider十分有用,其能使spider运行更快(不需要每次等待下载完成), 同时在没有网络连接时也能测试。 其目的是为了能够回放spider的运行过程, 使之与之前的运行过程一模一样

使用这个策略请设置:

RFC2616 policy

该策略提供了符合RFC2616的HTTP缓存,例如符合HTTP Cache-Control, 针对生产环境并且应用在持续性运行环境所设置,该策略能避免下载未修改的数据(来节省带宽,提高爬取速度)。

实现了:

  • no-storecache-control指令设置时不存储response/request

  • no-cache cache-control指定设置时不从cache中提取response,即使response为最新。

  • Compute freshness lifetime from max-age cache-control directive

  • Compute freshness lifetime from Expires response header

  • Compute freshness lifetime from Last-Modified response header (heuristic used by Firefox)

  • 根据response包头的 Age 计算当前年龄(current age)

  • 根据 Date 计算当前年龄(current age)

  • Revalidate stale responses based on Last-Modified response header

  • 根据response包头的 ETag 验证老旧的response。

  • 为接收到的response设置缺失的 Date 字段。

  • Support max-stale cache-control directive in requests

    这使Spider能配置充分的RFC2616高速缓存策略,但要避免request-by-request上的重复认证,而其余完全符合HTTP规范。

    示例︰

    添加Cache-Control: max-stale=600到Request头以接受已超出过期时间不超过600秒的响应。

    See also: RFC2616, 14.9.3

目前仍然缺失:

使用这个策略,设置:

Filesystem storage backend (default)

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

使用该存储端,设置:

每个request/response组存储在不同的目录中,包含下列文件:

  • request_body - the plain request body
  • request_headers - the request headers (原始HTTP格式)
  • response_body - the plain response body
  • response_headers - the request headers (原始HTTP格式)
  • meta - 以Python repr() 格式(grep-friendly格式)存储的该缓存资源的一些元数据。
  • pickled_meta - 与 meta 相同的元数据,不过使用pickle来获得更高效的反序列化性能。

目录的名称与request的指纹(参考 scrapy.utils.request.fingerprint)有关,而二级目录是为了避免在同一文件夹下有太多文件 (这在很多文件系统中是十分低效的)。 目录的例子:

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

DBM storage backend

New in version 0.13.

同时也有 DBM存储后端可以用于HTTP缓存中间件。

默认情况下,其采用 anydbm模块,不过您也可以通过 HTTPCACHE_DBM_MODULE设置进行修改。

使用该存储端,设置:

LevelDB storage backend

New in version 0.23.

A LevelDB storage backend is also available for the HTTP cache middleware.

This backend is not recommended for development because only one process can access LevelDB databases at the same time, so you can’t run a crawl and open the scrapy shell in parallel for the same spider.

In order to use this storage backend:

HTTPCache中间件设置

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

HTTPCACHE_ENABLED

New in version 0.11.

默认: False

HTTP缓存是否开启。

Changed in version 0.11: 在0.11版本前,是使用 HTTPCACHE_DIR 来开启缓存。

HTTPCACHE_EXPIRATION_SECS

默认: 0

缓存的request的超时时间,单位秒。

超过这个时间的缓存request将会被重新下载。 如果为0,则缓存的request将永远不会超时。

Changed in version 0.11: 在0.11版本前,0的意义是缓存的request永远超时。

HTTPCACHE_DIR

默认: 'httpcache'

存储(底层的)HTTP缓存的目录。 如果为空,则HTTP缓存将会被关闭。 如果为相对目录,则相对于项目数据目录(project data dir)。 更多内容请参考 默认的Scrapy项目结构

HTTPCACHE_IGNORE_HTTP_CODES

New in version 0.10.

默认: []

不缓存设置中的HTTP返回值(code)的request。

HTTPCACHE_IGNORE_MISSING

默认: False

如果启用,在缓存中没找到的request将会被忽略,不下载。

HTTPCACHE_IGNORE_SCHEMES

New in version 0.10.

默认: ['file']

不缓存这些URI标准(scheme)的response。

HTTPCACHE_STORAGE

默认: 'scrapy.contrib.httpcache.FilesystemCacheStorage'

实现缓存存储后端的类。

HTTPCACHE_DBM_MODULE

New in version 0.13.

默认: 'anydbm'

DBM存储后端 的数据库模块。 该设定针对DBM后端。

HTTPCACHE_POLICY

New in version 0.18.

默认: 'scrapy.contrib.httpcache.DummyPolicy'

实现缓存策略的类。

HTTPCACHE_GZIP

New in version 0.13.

默认: False

如果启用,将用gzip压缩所有缓存的数据。This setting is specific to the Filesystem backend.

HTTPCACHE_ALWAYS_STORE

New in version 1.1.

默认: False

If enabled, will cache pages unconditionally.

A spider may wish to have all responses available in the cache, for future use with Cache-Control: max-stale, for instance. The DummyPolicy caches all responses but never revalidates them, and sometimes a more nuanced policy is desirable.

This setting still respects Cache-Control: no-store directives in responses.If you don’t want that, filter no-store out of the Cache-Control headers in responses you feedto the cache middleware.

HTTPCACHE_IGNORE_RESPONSE_CACHE_CONTROLS

New in version 1.1.

默认: 20

List of Cache-Control directives in responses to be ignored.

Sites often set “no-store”, “no-cache”, “must-revalidate”, etc., but get upset at the traffic a spider can generate if it respects those directives. This allows to selectively ignore Cache-Control directives that are known to be unimportant for the sites being crawled.

We assume that the spider will not issue Cache-Control directives in requests unless it actually needs them, so directives in requests are not filtered.

HttpCompressionMiddleware

class scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware

该中间件提供了对压缩(gzip, deflate)数据的支持。

HttpCompressionMiddleware Settings

COMPRESSION_ENABLED

默认: True

Compression Middleware(压缩中间件)是否开启。

ChunkedTransferMiddleware

class scrapy.downloadermiddlewares.chunked.ChunkedTransferMiddleware

This middleware adds support for chunked transfer encoding

HttpProxyMiddleware

New in version 0.8.

class scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware

中间件提供了对request设置HTTP代理的支持,你可以通过在 Request 对象中设置 proxy 元数据来开启代理。

Like the Python standard library modules urllib and urllib2, it obeys the following environment variables:

  • http_proxy
  • https_proxy
  • no_proxy

You can also set the meta key proxy per-request, to a value like http://some_proxy_server:port.

RedirectMiddleware

class scrapy.downloadermiddlewares.redirect.RedirectMiddleware

该中间件根据response的状态处理重定向的request。

通过该中间件的(被重定向的)request的url可以通过 Request.metaredirect_urls 键找到。

The RedirectMiddleware can be configured through the following settings (see the settings documentation for more info):

如果 Request.metadont_redirect 设置为True ,则该request将会被此中间件忽略。

If you want to handle some redirect status codes in your spider, you can specify these in the handle_httpstatus_list spider attribute.

For example, if you want the redirect middleware to ignore 301 and 302 responses (and pass them through to your spider) you can do this:

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

The handle_httpstatus_list key of Request.meta can also be used to specify which response codes to allow on a per-request basis.You can also set the meta key handle_httpstatus_all to True if you want to allow any response code for a request.

RedirectMiddleware settings

REDIRECT_ENABLED

New in version 0.13.

Default: True

Retry Middleware是否启用。

REDIRECT_MAX_TIMES

Default: 20

单个request被重定向的最大次数。

MetaRefreshMiddleware

class scrapy.downloadermiddlewares.redirect.MetaRefreshMiddleware

该中间件根据meta-refresh html标签处理request重定向。

The MetaRefreshMiddleware can be configured through the following settings (see the settings documentation for more info):

This middleware obey REDIRECT_MAX_TIMES setting, dont_redirect and redirect_urls request meta keys as described for RedirectMiddleware

MetaRefreshMiddleware settings

METAREFRESH_ENABLED

New in version 0.17.

默认: True

Meta Refresh中间件是否启用。

METAREFRESH_MAXDELAY

默认: 100

跟进重定向的最大 meta-refresh 延迟(单位:秒)。 这是由于这些页面是在robots.txt被下载前被请求的。

RetryMiddleware

class scrapy.downloadermiddlewares.retry.RetryMiddleware

该中间件将重试可能由于临时的问题,例如连接超时或者HTTP 500错误导致失败的页面。

爬取进程会收集失败的页面并在最后,spider爬取完所有正常(不失败)的页面后重新调度。 一旦没有更多需要重试的失败页面,该中间件将会发送一个信号(retry_complete), 其他插件可以监听该信号。

The RetryMiddleware can be configured through the following settings (see the settings documentation for more info):

If Request.meta has dont_retry key set to True, the request will be ignored by this middleware.

RetryMiddleware Settings

RETRY_ENABLED

New in version 0.21.

默认: True

AjaxCrawlMiddleware是否启用。

RETRY_TIMES

默认: 2

包括第一次下载,最多的重试次数

RETRY_HTTP_CODES

Default: [500, 502, 503, 504, 408]

重试的response 返回值(code)。 其他错误(DNS查找问题、连接失败及其他)则一定会进行重试。

如果根据HTTP协议,您可能想要在设定 RETRY_HTTP_CODES 中移除400错误。 关于HTTP错误的考虑:

RobotsTxtMiddleware

class scrapy.downloadermiddlewares.robotstxt.RobotsTxtMiddleware

该中间件过滤所有robots.txt eclusion standard中禁止的request。

确认该中间件及 ROBOTSTXT_OBEY 设置被启用以确保Scrapy尊重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.

DownloaderStats

class scrapy.downloadermiddlewares.stats.DownloaderStats

保存所有通过的request、response及exception的中间件。

您必须启用 DOWNLOADER_STATS 来启用该中间件。

UserAgentMiddleware

class scrapy.downloadermiddlewares.useragent.UserAgentMiddleware

用于覆盖spider的默认user agent的中间件。

要使得spider能覆盖默认的user agent,其 user_agent 属性必须被设置。

AjaxCrawlMiddleware

class scrapy.downloadermiddlewares.ajaxcrawl.AjaxCrawlMiddleware

根据meta-fragment html标签查找 ‘AJAX可爬取’ 页面的中间件。 See https://developers.google.com/webmasters/ajax-crawling/docs/getting-started for more info.

Note

Scrapy finds ‘AJAX crawlable’ pages for URLs like 'http://example.com/!#foo=bar' even without this middleware. AjaxCrawlMiddleware is necessary when URL doesn’t contain '!#'. This is often a case for ‘index’ or ‘main’ website pages.

AjaxCrawlMiddleware Settings

AJAXCRAWL_ENABLED

New in version 0.21.

Default: False

Whether the AjaxCrawlMiddleware will be enabled. You may want to enable it for broad crawls.

HttpProxyMiddleware settings

HTTPPROXY_AUTH_ENCODING

Default: "latin-1"

The default encoding for proxy authentication on HttpProxyMiddleware.