下载器中间件是Scrapy的请求/响应处理中的钩子框架。 这是一个轻量级的低级系统,用于全球改变Scrapy的请求和响应。
激活一个下载器中间件
要激活下载器中间件组件,请将其添加到DOWNLOADER_MIDDLEWARES设置中,该设置是一个dict,其密钥是中间件类路径,其值是中间件订单。
这里有一个例子:
DOWNLOADER_MIDDLEWARES = {
'myproject.middlewares.CustomDownloaderMiddleware': 543,
}
DOWNLOADER_MIDDLEWARES设置与Scrapy中定义的DOWNLOADER_MIDDLEWARES_BASE设置合并(并不意味着被覆盖),然后按顺序排序,以获得启用的中间件的最终排序列表:第一个中间件是靠近引擎的最后一个中间件一个更接近下载器。换句话说,每个中间件的process_request()方法将以增加的中间件顺序(100,200,300,...)被调用,并且每个中间件的process_response()方法将以递减的顺序被调用。
要确定分配给您的中间件的顺序,请参阅DOWNLOADER_MIDDLEWARES_BASE设置,并根据您要插入中间件的位置选择一个值。该顺序是重要的,因为每个中间件都执行不同的操作,并且您的中间件可能依赖于一些先前(或后续的)中间件被应用。
如果要禁用内置中间件(在DOWNLOADER_MIDDLEWARES_BASE中定义并在默认情况下启用),必须在项目的“DOWNLOADER_MIDDLEWARES”设置中定义它,并将“无”作为其值。例如,如果要禁用用户代理中间件:
最后,请记住,一些中间件可能需要通过特定设置启用。 有关更多信息,请参阅每个中间件文档。
编写自己的下载中间件
每个中间件组件都是一个Python类,它定义了一个或多个以下方法:
类scrapy.downloadermiddlewares.DownloaderMiddleware
注意
任何下载中间件方法也可能返回延期。
process_request(请求,蜘蛛)
对于通过下载中间件的每个请求都调用此方法。
process_request()应该:返回None,返回一个Response对象,返回一个Request对象,或者提高IgnoreRequest。
如果返回None,Scrapy将继续处理此请求,执行所有其他中间件,直到最后,适当的下载程序处理程序称为执行请求(并且其响应已下载)。
如果它返回一个Response对象,Scrapy不会打扰任何其他process_request()或process_exception()方法,或者适当的下载功能;它会返回该响应。安装的中间件的process_response()方法总是在每个响应中调用。
如果它返回一个Request对象,Scrapy将停止调用process_request方法并重新计划返回的请求。一旦执行了新返回的请求,将在下载的响应中调用相应的中间件链。
如果它引发了IgnoreRequest异常,则将调用安装的下载器中间件的process_exception()方法。如果没有一个处理异常,则调用请求(Request.errback)的errback函数。如果没有代码处理引发的异常,它将被忽略而不记录(与其他异常不同)。
参数:
请求(请求对象) - 正在处理的请求
蜘蛛(Spider对象) - 这个请求的蜘蛛
process_response(请求,响应,蜘蛛)
process_response()应该:返回一个Response对象,返回一个Request对象或引发一个IgnoreRequest异常。
如果它返回响应(它可能是相同的给定响应或全新的响应),该响应将继续使用链中的下一个中间件的process_response()进行处理。
如果它返回一个Request对象,则中间件链被暂停,并且返回的请求被重新安排以便将来被下载。这与从process_request()返回请求相同的行为。
如果它引发了IgnoreRequest异常,则调用请求(Request.errback)的errback函数。如果没有代码处理引发的异常,它将被忽略而不记录(与其他异常不同)。
参数:
request(是一个Request对象) - 发起响应的请求
响应(响应对象) - 正在处理的响应
蜘蛛(Spider对象) - 这个响应是打算的蜘蛛
process_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对象) - 生成异常的请求
异常(异常对象) - 引发的异常
蜘蛛(Spider对象) - 这个请求的蜘蛛
内置下载器中间件参考
本页面描述了Scrapy附带的所有下载器中间件组件。有关如何使用它们以及如何编写自己的下载器中间件的信息,请参阅下载中间件使用指南。
有关默认启用的组件(及其顺序)的列表,请参阅DOWNLOADER_MIDDLEWARES_BASE设置。
CookiesMiddleware
类scrapy.downloadermiddlewares.cookies.Cookies中间件
这个中间件可以使用需要cookie的站点,比如使用会话的站点。它跟踪Web服务器发送的Cookie,并将其发送回来(后来的蜘蛛)请求,就像网络浏览器一样。
以下设置可用于配置Cookie中间件:
COOKIES_ENABLED
COOKIES_DEBUG
每个蜘蛛多个cookie会话
新版本0.15。
通过使用cookiejar请求元键来支持每个蜘蛛保持多个cookie会话。默认情况下,它使用单个cookie jar(session),但是可以传递一个标识符来使用不同的cookie。
例如:
请记住,cookiejar元键不是“粘性”。您需要根据后续请求继续传递。例如:
def parse_page(self,response):
#做一些处理
返回scrapy.Request(“http://www.example.com/otherpage”,
meta = {'cookiejar':response.meta \['cookiejar'\]},
回调= self.parse\_other\_page)
COOKIES_ENABLED
默认值:True
是否启用Cookie中间件。如果禁用,则不会将cookie发送到Web服务器。
COOKIES_DEBUG
默认值:False
如果启用,Scrapy将记录在请求(即Cookie头)中发送的所有Cookie和响应中收到的所有Cookie(即Set-Cookie头文件)。
以下是启用COOKIES_DEBUG的日志示例:
2011-04-06 14:35:10-0300 [scrapy.core.engine]信息:蜘蛛打开
2011-04-06 14:35:10-0300 [scrapy.downloadermiddlewares.cookies]调试:发送cookies到:<GET http://www.diningcity.com/netherlands/index.html>
Cookie:clientlanguage\_nl = en\_EN
2011-04-06 14:35:14-0300 [scrapy.downloadermiddlewares.cookies] DEBUG:收到的Cookie来自:<200 http://www.diningcity.com/netherlands/index.html>
Set-Cookie:JSESSIONID = B〜FA4DC0C496C8762AE4F1A620EAB34F38;路径= /
Set-Cookie:ip\_isocode = US
Set-Cookie:clientlanguage\_nl = en\_EN; Expires = Thu,07-Apr-2011 21:21:34 GMT;路径= /
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属性中指定的请求设置下载超时。
注意
您还可以使用download_timeout Request.meta密钥设置每个请求的下载超时时间;即使禁用了DownloadTimeoutMiddleware,也是受支持的。
HttpAuthMiddleware
class scrapy.downloadermiddlewares.httpauth.HttpAuthMiddleware
该中间件使用基本访问认证(也称为HTTP auth)来验证从某些蜘蛛生成的所有请求。
要启用某些蜘蛛的HTTP身份验证,请设置这些蜘蛛的http_user和http_pass属性。
例:
从scrapy.spiders导入CrawlSpider
SomeIntranetSiteSpider(CrawlSpider)类:
http\_user ='someuser'
http\_pass ='somepass'
name ='intranet.example.com'
其余的蜘蛛代码省略...
HttpCacheMiddleware
class scrapy.downloadermiddlewares.httpcache.HttpCacheMiddleware
该中间件为所有HTTP请求和响应提供低级缓存。它必须与高速缓存存储后端以及高速缓存策略相结合。
具有三个HTTP缓存存储后端的Scrapy船:
文件系统存储后端(默认)
DBM存储后端
LevelDB存储后端
您可以使用HTTPCACHE_STORAGE设置更改HTTP缓存存储后端。或者您也可以实现自己的存储后端。
具有两个HTTP缓存策略的Scrapy船:
RFC2616政策
虚拟策略(默认)
您可以使用HTTPCACHE_POLICY设置更改HTTP缓存策略。或者您也可以实施自己的策略。
您还可以避免使用dont_cache元键等于True在每个策略上缓存响应。
虚拟策略(默认)
该策略没有任何HTTP Cache-Control指令的意识。每个请求及其相应的响应都被缓存。当再次看到相同的请求时,返回响应而不从Internet传输任何内容。
虚拟策略对于快速测试蜘蛛(无需每次都等待下载)以及当Internet连接不可用时尝试脱离蜘蛛时很有用。目标是能够像以前一样“重播”一个蜘蛛运行。
为了使用这个策略,设置:
HTTPCACHE_POLICY to scrapy.extensions.httpcache.DummyPolicy
RFC2616政策
该策略提供了符合RFC2616标准的HTTP缓存,即HTTP缓存控制意识,旨在生产并用于连续运行,以避免下载未修改的数据(以节省带宽并加快爬网)。
什么是实现:
不要尝试存储响应/请求与无存储缓存控制指令集
如果即使对于新的响应也设置了高速缓存缓存控制指令,则不要为缓存提供响应
从max-age cache-control指令计算新鲜度的生命周期
从Expires响应头计算新鲜度的生命周期
从Last-Modified响应头(Firefox使用的启发式)计算新鲜度的生命周期
从Age响应头计算当前年龄
从Date标头计算当前年龄
根据Last-Modified响应头重新生效陈旧的响应
根据ETag响应头重新生效陈旧的响应
任何收到的响应的Set Date标题丢失
在请求中支持max-stale缓存控制指令
这允许Spider配置完整的RFC2616高速缓存策略,但是避免在逐个请求的基础上重新验证,同时仍然符合HTTP规范。
例:
添加缓存控制:max-stale = 600请求标头接受超过其过期时间不超过600秒的响应。
另见RFC2616,14.9.3
什么不见了:
Pragma:无缓存支持https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html\#sec14.9.1
Vary标头支持https://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html\#sec13.6
更新或删除后无效https://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html\#sec13.10
...大概其他..
为了使用这个策略,设置:
HTTPCACHE_POLICY to scrapy.extensions.httpcache.RFC2616Policy
文件系统存储后端(默认)
文件系统存储后端可用于HTTP缓存中间件。
为了使用这个存储后端,设置:
HTTPCACHE_STORAGE to scrapy.extensions.httpcache.FilesystemCacheStorage
每个请求/响应对都存储在包含以下文件的不同目录中:
request_body - 简单的请求体
request_headers - 请求头(原始HTTP格式)
response_body - 平原响应体
response_headers - 请求头(原始HTTP格式)
元数据 - 这个缓存资源的一些元数据在Python repr()格式(grep-friendly格式)
pickled_meta - 元数据中相同的元数据,但为了更高效的反序列化而被腌制
目录名称由请求指纹(见scrapy.utils.request.fingerprint)构成,一级子目录用于避免在同一目录中创建太多文件(这在许多文件系统中效率低下)。示例目录可以是:
/path/to/cache/dir/example.com/72/72811f648e718090f041317756c03adb0ada46c7
DBM存储后端
0.13版新功能
HTTP缓存中间件也可以使用DBM存储后端。
默认情况下,它使用anydbm模块,但您可以使用HTTPCACHE_DBM_MODULE设置进行更改。
为了使用这个存储后端,设置:
HTTPCACHE_STORAGE to scrapy.extensions.httpcache.DbmCacheStorage
LevelDB存储后端
新版本0.23。
一个LevelDB存储后端也可用于HTTP缓存中间件。
该后端不推荐用于开发,因为只有一个进程可以同时访问LevelDB数据库,因此您无法对同一个蜘蛛并行运行爬网并打开scrapy shell。
为了使用这个存储后端:
将HTTPCACHE_STORAGE设置为scrapy.extensions.httpcache.LeveldbCacheStorage
安装LevelDB python绑定,如pip install leveldb
HTTPCache中间件设置
HttpCacheMiddleware可以通过以下设置进行配置:
HTTPCACHE_ENABLED
0.11版新功能
默认值:False
是否启用HTTP缓存。
在0.11版更改:0.11之前,HTTPCACHE_DIR用于启用缓存。
HTTPCACHE_EXPIRATION_SECS
默认值:0
缓存请求的到期时间,以秒为单位。
超过此时间的缓存请求将被重新下载。如果为零,缓存请求永远不会过期。
0.11版更改:0.11之前,零表示缓存请求总是过期。
HTTPCACHE_DIR
默认值:'httpcache'
用于存储(低级)HTTP缓存的目录。如果为空,则HTTP缓存将被禁用。如果给出相对路径,则相对于项目数据目录采用。欲了解更多信息,请参阅:Scrapy项目的默认结构。
HTTPCACHE_IGNORE_HTTP_CODES
新版本0.10。
默认值:[]
不要使用这些HTTP代码来缓存响应。
HTTPCACHE_IGNORE_MISSING
默认值:False
如果启用,缓存中找不到的请求将被忽略,而不是下载。
HTTPCACHE_IGNORE_SCHEMES
新版本0.10。
默认值:['file']
不要使用这些URI方案来缓存响应。
HTTPCACHE_STORAGE
默认值:'scrapy.extensions.httpcache.FilesystemCacheStorage'
实现缓存存储后端的类。
HTTPCACHE_DBM_MODULE
0.13版新功能
默认值:'anydbm'
数据库模块用于DBM存储后端。此设置特定于DBM后端。
HTTPCACHE_POLICY
0.18版新功能
默认值:'scrapy.extensions.httpcache.DummyPolicy'
实现缓存策略的类。
HTTPCACHE_GZIP
新版本1.0。
默认值:False
如果启用,将使用gzip压缩所有缓存的数据。此设置特定于文件系统后端。
HTTPCACHE_ALWAYS_STORE
1.1版新功能
默认值:False
如果启用,将无条件缓存页面。
例如,蜘蛛可能希望在缓存中提供所有响应,以备将来使用Cache-Control:max-stale。 DummyPolicy缓存所有响应,但不会重新验证它们,有时候更有微妙的策略是可取的。
此设置仍然遵循缓存控制:响应中的无存储指令。如果您不想要,请将缓存控制头部的缓存过滤器保存到缓存中间件的响应中。
HTTPCACHE_IGNORE_RESPONSE_CACHE_CONTROLS
1.1版新功能
默认值:[]
Cache-Control指令列表在响应中被忽略。
站点经常设置“无存储”,“无缓存”,“必须重新验证”等,但是如果遵守这些指令,蜘蛛可以生成的流量感到不安。这允许选择性地忽略对被抓取的站点不重要的Cache-Control指令。
我们假设蜘蛛不会在请求中发出Cache-Control伪指令,除非实际需要它们,因此请求中的指令不被过滤。
HttpCompressionMiddleware
class scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware
这个中间件允许从网站发送/接收压缩(gzip,deflate)流量。
这个中间件还支持解码brotli压缩的响应,只要安装了brotlipy。
HttpCompressionMiddleware设置
COMPRESSION_ENABLED
默认值:True
压缩中间件是否启用
HttpProxyMiddleware
新版本0.8。
class scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware
该中间件通过为Request对象设置代理元值来设置HTTP代理用于请求。
像Python标准库模块urllib和urllib2一样,它遵循以下环境变量:
HTTP_PROXY
https_proxy
NO_PROXY
您还可以将元关键代理每个请求设置为一个值,如http:// some_proxy_server:port或http:// username:password @ some_proxy_server:port。请记住,这个值将优先于http_proxy / https_proxy环境变量,它也将忽略no_proxy环境变量。
RedirectMiddleware
class scrapy.downloadermiddlewares.redirect.RedirectMiddleware
该中间件根据响应状态处理请求的重定向。
请求遍历(同时被重定向)的URL可以在redirect_urls Request.meta密钥中找到。
RedirectMiddleware可以通过以下设置进行配置(有关详细信息,请参阅设置文档):
REDIRECT_ENABLED
REDIRECT_MAX_TIMES
如果Request.meta的dont_redirect键设置为True,则该中间件将忽略该请求。
如果要处理蜘蛛中的某些重定向状态代码,可以在handle_httpstatus_list spider属性中指定这些代码。
例如,如果您希望重定向中间件忽略301和302响应(并将其传递给您的蜘蛛),您可以这样做:
MySpider类(CrawlSpider):
handle\_httpstatus\_list = \[301,302\]
Request.meta的handle_httpstatus_list键也可用于指定每个请求允许的响应代码。如果要允许请求的任何响应代码,还可以将元键handle_httpstatus_all设置为True。
重定向中间件设置
REDIRECT_ENABLED
0.13版新功能
默认值:True
是否启用重定向中间件。
REDIRECT_MAX_TIMES
默认值:20
单个请求将遵循的最大重定向数。
MetaRefreshMiddleware
class scrapy.downloadermiddlewares.redirect.MetaRefreshMiddleware
该中间件处理基于元刷新html标签的请求重定向。
MetaRefreshMiddleware可以通过以下设置进行配置(有关详细信息,请参阅设置文档):
METAREFRESH_ENABLED
METAREFRESH_MAXDELAY
这个中间件遵循REDIRECT_MAX_TIMES设置,dont_redirect和redirect_urls请求元密钥,如RedirectMiddleware所述
MetaRefreshMiddleware设置
METAREFRESH_ENABLED
新版本0.17。
默认值:True
Meta Refresh中间件是否启用。
METAREFRESH_MAXDELAY
默认值:100
按照重定向的最大元刷新延迟(以秒为单位)。某些网站使用元刷新重定向到会话过期页面,因此我们将自动重定向限制为最大延迟。
RetryMiddleware
类scrapy.downloadermiddlewares.retry.RetryMiddleware
中间件重试可能由临时问题(如连接超时或HTTP 500错误)引起的失败请求。
一旦蜘蛛已经完成了所有常规(非失败)页面的爬行,页面都将在抓取过程中收集并重新排列。一旦没有更多失败的页面重试,这个中间件发送信号(retry_complete),所以其他扩展可以连接到该信号。
可以通过以下设置配置RetryMiddleware(有关详细信息,请参阅设置文档):
RETRY_ENABLED
RETRY_TIMES
RETRY_HTTP_CODES
如果Request.meta的dont_retry键设置为True,则该中间件将忽略该请求。
重试中间件设置
RETRY_ENABLED
0.13版新功能
默认值:True
是否启用重试中间件。
RETRY_TIMES
默认值:2
除了第一次下载外,还要重试的最大次数。
也可以使用request.meta的max_retry_times属性为每个请求指定最大重试次数。初始化时,max_retry_times元键的优先级高于RETRY_TIMES设置。
RETRY_HTTP_CODES
默认值:[500,502,503,504,408]
要重试的HTTP响应代码。总是重试其他错误(DNS查找问题,连接丢失等)。
在某些情况下,您可能需要添加400到RETRY_HTTP_CODES,因为它是用于指示服务器超负荷的通用代码。默认情况下不包括HTTP规范。
RobotsTxtMiddleware
class scrapy.downloadermiddlewares.robotstxt.RobotsTxtMiddleware
此中间件过滤掉robots.txt排除标准所禁止的请求。
要确保Scrapy尊重robots.txt,请确保启用了中间件,并启用了ROBOTSTXT_OBEY设置。
如果Request.meta将dont_obey_robotstxt键设置为True,即使启用了ROBOTSTXT_OBEY,该中间件也将忽略该请求。
DownloaderStats
class scrapy.downloadermiddlewares.stats.DownloaderStats
存储通过它的所有请求,响应和异常的统计信息的中间件。
要使用此中间件,您必须启用DOWNLOADER_STATS设置。
UserAgentMiddleware
class scrapy.downloadermiddlewares.useragent.UserAgentMiddleware
允许蜘蛛覆盖默认用户代理的中间件。
为了使蜘蛛覆盖默认用户代理,必须设置其user_agent属性。
AjaxCrawlMiddleware
class scrapy.downloadermiddlewares.ajaxcrawl.AjaxCrawlMiddleware
基于meta-fragment html标签找到“AJAX可抓取”页面变体的中间件。有关详细信息,请参阅https://developers.google.com/webmasters/ajax-crawling/docs/getting-started。
注意
AjaxCrawlMiddleware设置
AJAXCRAWL_ENABLED
新版本0.21。
默认值:False
是否启用AjaxCrawlMiddleware。您可能需要启用它进行大量爬网。
HttpProxyMiddleware设置
HTTPPROXY_ENABLED
默认值:True
是否启用HttpProxyMiddleware。
HTTPPROXY_AUTH_ENCODING
默认值:“latin-1”
HttpProxyMiddleware上的代理身份验证的默认编码。