小白学 Python 爬虫(36):爬虫框架 Scrapy 入门基础(四) Downloader Middleware
人生苦短,我用 Python
前文传送门:
小白学 Python 爬虫(2):前置准备(一)基本类库的安装
小白学 Python 爬虫(3):前置准备(二)Linux基础入门
小白学 Python 爬虫(4):前置准备(三)Docker基础入门
小白学 Python 爬虫(6):前置准备(五)爬虫框架的安装
小白学 Python 爬虫(10):Session 和 Cookies
小白学 Python 爬虫(11):urllib 基础使用(一)
小白学 Python 爬虫(12):urllib 基础使用(二)
小白学 Python 爬虫(13):urllib 基础使用(三)
小白学 Python 爬虫(14):urllib 基础使用(四)
小白学 Python 爬虫(15):urllib 基础使用(五)
小白学 Python 爬虫(16):urllib 实战之爬取妹子图
小白学 Python 爬虫(17):Requests 基础使用
小白学 Python 爬虫(18):Requests 进阶操作
小白学 Python 爬虫(21):解析库 Beautiful Soup(上)
小白学 Python 爬虫(22):解析库 Beautiful Soup(下)
小白学 Python 爬虫(23):解析库 pyquery 入门
小白学 Python 爬虫(26):为啥买不起上海二手房你都买不起
小白学 Python 爬虫(27):自动化测试框架 Selenium 从入门到放弃(上)
小白学 Python 爬虫(28):自动化测试框架 Selenium 从入门到放弃(下)
小白学 Python 爬虫(29):Selenium 获取某大型电商网站商品信息
小白学 Python 爬虫(31):自己构建一个简单的代理池
小白学 Python 爬虫(32):异步请求库 AIOHTTP 基础入门
小白学 Python 爬虫(33):爬虫框架 Scrapy 入门基础(一)
小白学 Python 爬虫(34):爬虫框架 Scrapy 入门基础(二)
小白学 Python 爬虫(35):爬虫框架 Scrapy 入门基础(三) Selector 选择器
引言
Downloader Middleware 直译过来是下载器中间件,本文后续就叫它下载中间件了。
下载器中间件主要用于 Scrapy 的 Request 和 Response 处理。
Downloader Middleware 的功能非常的强大,可以修改 UA 头、处理重定向、设置代理、设置超时时间、失败重试、设置 Cookies 等功能。
内置下载器中间件
Scrapy 已经为我们提供相当多的内置的下载器中间件,用于各种功能,列表如下:
{
'scrapy.downloadermiddlewares.robotstxt.RobotsTxtMiddleware': 100,
'scrapy.downloadermiddlewares.httpauth.HttpAuthMiddleware': 300,
'scrapy.downloadermiddlewares.downloadtimeout.DownloadTimeoutMiddleware': 350,
'scrapy.downloadermiddlewares.defaultheaders.DefaultHeadersMiddleware': 400,
'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware': 500,
'scrapy.downloadermiddlewares.retry.RetryMiddleware': 550,
'scrapy.downloadermiddlewares.ajaxcrawl.AjaxCrawlMiddleware': 560,
'scrapy.downloadermiddlewares.redirect.MetaRefreshMiddleware': 580,
'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware': 590,
'scrapy.downloadermiddlewares.redirect.RedirectMiddleware': 600,
'scrapy.downloadermiddlewares.cookies.CookiesMiddleware': 700,
'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware': 750,
'scrapy.downloadermiddlewares.stats.DownloaderStats': 850,
'scrapy.downloadermiddlewares.httpcache.HttpCacheMiddleware': 900,
}
这些列表定义在 DOWNLOADER_MIDDLEWARES_BASE
变量中。
这些列表的数据结构是一个字典格式,后面的值代表了优先级,数字越小代表了越靠近 Scrapy 引擎,数字越大越靠近下载器,数字小的会被优先调用。
自定义下载器中间件
如果要在项目自定义一个下载器中间件,需要我们自己设置 DOWNLOADER_MIDDLEWARES
这个变量,这个变量位于 settings.py ,默认是注释状态,当我们需要的时候直接打开这个注释就可以了,这里不仅可以自定义我们所需要的下载器中间件,还可以禁用 DOWNLOADER_MIDDLEWARES_BASE
中定义的下载器中间件。
每个下载器中间件都是一个Python类,该类定义了以下定义的一个或多个方法。
核心方法共有 4 个,如下:
- process_request(request, spider)
- process_response(request, response, spider)
- process_exception(request, exception, spider)
- from_crawler(cls, crawler)
而我们至少只需要实现其中的一个方法就可以定义一个下载器中间件。
process_request(request, spider)
参数:
- request(Request对象)–正在处理的请求
- spider(Spider对象)–此请求所针对的蜘蛛
对于通过下载中间件的每个请求,都会调用此方法。
process_request() 应该是:return None,返回一个 Response 对象,返回一个Request 对象或引发 IgnoreRequest 异常。
如果返回 None ,则 Scrapy 将继续处理此请求,执行所有其他中间件,直到最终将适当的下载程序处理程序称为执行的请求(并下载了其响应)。
如果它返回一个 Response 对象, Scrapy 不会打扰调用任何其他 process_request() 或 process_exception() 方法,或相应的下载功能; 它将返回该响应。 process_response() 总是在每个响应上调用已安装中间件的方法。
如果返回一个 Request 对象, Scrapy 将停止调用 process_request 方法并重新计划返回的请求。一旦执行了新返回的请求,就会在下载的响应上调用适当的中间件链。
如果引发 IgnoreRequest 异常,则所有的下载器中间件的方法 process_exception() 会依次执行,如果没有一个方法处理该异常,那么 Request 的 errback() 方法就会回调,如果该异常还没处理,那么就会忽略。
process_response(request, response, spider)
参数:
- request (是一个 Request 对象)–发起响应的请求
- response (response 对象)–正在处理的响应
- spider (spider 对象)–此响应预期用于的蜘蛛
process_response() 应该:返回响应对象,返回请求对象或引发 IgnoreRequest 异常。
如果它返回一个 Response (它可以是相同的给定响应,也可以是全新的响应),那么该响应将继续使用链中下一个中间件的 process_response() 进行处理。
如果它返回一个 Request 对象,则中间件链将暂停,并将返回的请求重新安排为将来下载。 这与从 process_request() 返回请求的行为相同。
如果引发 IgnoreRequest 异常,则调用请求的 errback 函数(Request.errback)。 如果没有代码处理引发的异常,则将其忽略并且不记录(与其他异常不同)。
process_exception(request, exception, spider)
参数:
- request (是一个Request对象)–生成异常的请求
- exception (Exception对象)–引发的异常
- spider (spider对象)–此请求所针对的蜘蛛
当下载处理程序或 process_request() (从下载程序中间件中)引发异常(包括 IgnoreRequest 异常)时, Scrapy 会调用 process_exception() 。
process_exception() 应该返回:无,响应对象或请求对象。
如果返回 None ,则 Scrapy 将继续处理此异常,执行已安装中间件的任何其他 process_exception() 方法,直到没有中间件为止,并且默认异常处理开始。
如果返回 Response 对象,则会启动已安装中间件的 process_response() 方法链,并且 Scrapy 不会费心调用中间件的任何其他 process_exception() 方法。
如果它返回一个 Request 对象,则将返回的请求重新安排为将来下载。 这将停止执行中间件的 process_exception() 方法,就像返回响应一样。
from_crawler(cls, crawler)
参数:
- crawler(搜寻器对象)–使用此中间件的搜寻器
如果存在,则调用该类方法以从 Crawler 创建中间件实例。 它必须返回中间件的新实例。 搜寻器对象提供对所有 Scrapy 核心组件(如设置和信号)的访问; 它是中间件访问它们并将其功能连接到 Scrapy 中的一种方式。
示例
首先,我们还是在前面的 Scrapy 的项目上新建一个 Spider ,具体代码如下:
# -*- coding: utf-8 -*-
import scrapy
class HttpbinSpider(scrapy.Spider):
name = 'httpbin'
allowed_domains = ['httpbin.org']
start_urls = ['https://httpbin.org/get']
def parse(self, response):
self.logger.debug(response.text)
使用如下命令运行一下:
scrapy crawl httpbin
结果部分截取如下:
{
"args": {},
"headers": {
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Accept-Encoding": "gzip,deflate,br",
"Accept-Language": "en",
"Host": "httpbin.org",
"User-Agent": "Scrapy/1.8.0 (+https://scrapy.org)"
},
"origin": "183.195.68.215, 183.195.68.215",
"url": "https://httpbin.org/get"
}
可以看到,这里的 UA 头是 Scrapy/1.8.0 (+https://scrapy.org)
,这个其实是由 Scrapy 内置的 UserAgentMiddleware
设置的。
这里我们通过修改一下 UA 头,当然修改 UA 头可以通过 settings 中的 USER_AGENT 进行设置,这里我们要演示下载器中间件嘛,所以就使用下载器中间件设置一下。
首先我们在 middlewares.py
中新增一个 UaDownLoaderMiddleware ,示例代码如下:
class UaDownLoaderMiddleware(object):
def process_request(self, request, spider):
request.headers['User-Agent'] = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36'
新增完成后,还需要在配置文件 settings 中开启这个下载器中间件,找到 DOWNLOADER_MIDDLEWARES
,将注释去掉,修改为:
DOWNLOADER_MIDDLEWARES = {
'first_scrapy.middlewares.UaDownLoaderMiddleware': 543,
}
到这里,我们的修改就完成了,可以重新运行这只爬虫:
scrapy crawl httpbin
结果部分截取如下:
{
"args": {},
"headers": {
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Accept-Encoding": "gzip,deflate,br",
"Accept-Language": "en",
"Host": "httpbin.org",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36"
},
"origin": "183.195.68.215, 183.195.68.215",
"url": "https://httpbin.org/get"
}
可以看到,这里响应的 UA 已经变成了我们刚才设置的 UA 头,证明我们的修改是成功的。
本篇就先到这里了,希望各位同学可以自己动手试一下。
示例代码
本系列的所有代码小编都会放在代码管理仓库 Github 和 Gitee 上,方便大家取用。
参考
https://docs.scrapy.org/en/latest/topics/settings.html#std:setting-DOWNLOADER_MIDDLEWARES_BASE
https://docs.scrapy.org/en/latest/topics/downloader-middleware.html
小白学 Python 爬虫(36):爬虫框架 Scrapy 入门基础(四) Downloader Middleware的更多相关文章
- 小白学 Python 爬虫(37):爬虫框架 Scrapy 入门基础(五) Spider Middleware
人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...
- 小白学 Python 爬虫(38):爬虫框架 Scrapy 入门基础(六) Item Pipeline
人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...
- 小白学 Python 爬虫(40):爬虫框架 Scrapy 入门基础(七)对接 Selenium 实战
人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...
- 小白学 Python 爬虫(41):爬虫框架 Scrapy 入门基础(八)对接 Splash 实战
人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...
- 小白学 Python 爬虫(34):爬虫框架 Scrapy 入门基础(二)
人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...
- 小白学 Python 爬虫(35):爬虫框架 Scrapy 入门基础(三) Selector 选择器
人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...
- 小白学 Python 数据分析(5):Pandas (四)基础操作(1)查看数据
在家为国家做贡献太无聊,不如跟我一起学点 Python 人生苦短,我用 Python 前文传送门: 小白学 Python 数据分析(1):数据分析基础 小白学 Python 数据分析(2):Panda ...
- 小白学 Python 数据分析(19):Matplotlib(四)常用图表(下)
人生苦短,我用 Python 前文传送门: 小白学 Python 数据分析(1):数据分析基础 小白学 Python 数据分析(2):Pandas (一)概述 小白学 Python 数据分析(3):P ...
- 小白学 Python 爬虫(33):爬虫框架 Scrapy 入门基础(一)
人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...
随机推荐
- g++ 编译单个文件和多个文件
转载:https://www.cnblogs.com/battlescars/p/cpp_linux_gcc.html 1.单个源文件生成可执行程序 下面是一个保存在文件 helloworld.cpp ...
- 洛谷 2403 [SDOI2010] 所驼门王的宝藏
题目描述 在宽广的非洲荒漠中,生活着一群勤劳勇敢的羊驼家族.被族人恭称为“先知”的Alpaca L. Sotomon是这个家族的领袖,外人也称其为“所驼门王”.所驼门王毕生致力于维护家族的安定与和谐, ...
- MVC插件式开发平台
---恢复内容开始--- 经过DyOS.BraveOS1.0再到BraveOS2.0,系统现在已经开发了下载. 我们的目标是,网页版操作系统,可以在线安装更新软件,并提供二次开发平台,提供基础的逻辑和 ...
- 如何创建私有pod三方库
1.先登录github或者开源中国码云,创建远程仓库,用来存放库文件代码 仓库创建完成,得到远程仓库地址,并保存备用 2.创建本地代码库 打开终端,cd到你想创建的文件夹下,使用命令:pod lib ...
- Laravel 中config的用法
Laravel的config下一般存放配置信息,可以通过config('key')方法获取指定的数据. 设置值可通过「点」式语法读取,其中包含要访问的文件名以及选项名称. 现在想读取\config\a ...
- H3C Basic NAT
- H3C 入站包过滤工作流程
- Vue vue-resource三种请求数据方式pet,post,jsonp
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Roslyn 使用 WriteLinesToFile 解决参数过长无法传入
在写 Roslyn 的时候,经常需要辅助编译的工具,而这些工具需要传入一些参数,在项目很大的时候,会发现自己传入的参数比微软限制控制台可以传入的参数大很多,这时就无法传入了参数 本文告诉大家如何使用 ...
- 2019牛客暑期多校训练营(第二场)F.Partition problem
链接:https://ac.nowcoder.com/acm/contest/882/F来源:牛客网 Given 2N people, you need to assign each of them ...