Downloader Middleware

源码解析:

 1 # 文件:E:\Miniconda\Lib\site-packages\scrapy\core\downloader\middleware.py
 2 """
 3 Downloader Middleware manager
 4
 5 See documentation in docs/topics/downloader-middleware.rst
 6 """
 7 import six
 8
 9 from twisted.internet import defer
10
11 from scrapy.http import Request, Response
12 from scrapy.middleware import MiddlewareManager
13 from scrapy.utils.defer import mustbe_deferred
14 from scrapy.utils.conf import build_component_list
15
16
17 class DownloaderMiddlewareManager(MiddlewareManager):
18
19     component_name = 'downloader middleware'
20
21     @classmethod
22     def _get_mwlist_from_settings(cls, settings):
23         # 从settings.py或这custom_setting中拿到自定义的Middleware中间件
24         '''
25         'DOWNLOADER_MIDDLEWARES': {
26             'mySpider.middlewares.ProxiesMiddleware': 400,
27             # SeleniumMiddleware
28             'mySpider.middlewares.SeleniumMiddleware': 543,
29             'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware': None,
30         },
31         '''
32         return build_component_list(
33             settings.getwithbase('DOWNLOADER_MIDDLEWARES'))
34
35     # 将所有自定义Middleware中间件的处理函数添加到对应的methods列表中
36     def _add_middleware(self, mw):
37         if hasattr(mw, 'process_request'):
38             self.methods['process_request'].append(mw.process_request)
39         if hasattr(mw, 'process_response'):
40             self.methods['process_response'].insert(0, mw.process_response)
41         if hasattr(mw, 'process_exception'):
42             self.methods['process_exception'].insert(0, mw.process_exception)
43
44     # 整个下载流程
45     def download(self, download_func, request, spider):
46         @defer.inlineCallbacks
47         def process_request(request):
48             # 处理request请求,依次经过各个自定义Middleware中间件的process_request方法,前面有加入到list中
49             for method in self.methods['process_request']:
50                 response = yield method(request=request, spider=spider)
51                 assert response is None or isinstance(response, (Response, Request)), \
52                         'Middleware %s.process_request must return None, Response or Request, got %s' % \
53                         (six.get_method_self(method).__class__.__name__, response.__class__.__name__)
54                 # 这是关键地方
55                 # 如果在某个Middleware中间件的process_request中处理完之后,生成了一个response对象
56                 # 那么会直接将这个response return 出去,跳出循环,不再处理其他的process_request
57                 # 之前我们的header,proxy中间件,都只是加个user-agent,加个proxy,并不做任何return值
58                 # 还需要注意一点:就是这个return的必须是Response对象
59                 # 后面我们构造的HtmlResponse正是Response的子类对象
60                 if response:
61                     defer.returnValue(response)
62             # 如果在上面的所有process_request中,都没有返回任何Response对象的话
63             # 最后,会将这个加工过的Request送往download_func,进行下载,返回的就是一个Response对象
64             # 然后依次经过各个Middleware中间件的process_response方法进行加工,如下
65             defer.returnValue((yield download_func(request=request,spider=spider)))
66
67         @defer.inlineCallbacks
68         def process_response(response):
69             assert response is not None, 'Received None in process_response'
70             if isinstance(response, Request):
71                 defer.returnValue(response)
72
73             for method in self.methods['process_response']:
74                 response = yield method(request=request, response=response,
75                                         spider=spider)
76                 assert isinstance(response, (Response, Request)), \
77                     'Middleware %s.process_response must return Response or Request, got %s' % \
78                     (six.get_method_self(method).__class__.__name__, type(response))
79                 if isinstance(response, Request):
80                     defer.returnValue(response)
81             defer.returnValue(response)
82
83         @defer.inlineCallbacks
84         def process_exception(_failure):
85             exception = _failure.value
86             for method in self.methods['process_exception']:
87                 response = yield method(request=request, exception=exception,
88                                         spider=spider)
89                 assert response is None or isinstance(response, (Response, Request)), \
90                     'Middleware %s.process_exception must return None, Response or Request, got %s' % \
91                     (six.get_method_self(method).__class__.__name__, type(response))
92                 if response:
93                     defer.returnValue(response)
94             defer.returnValue(_failure)
95
96         deferred = mustbe_deferred(process_request, request)
97         deferred.addErrback(process_exception)
98         deferred.addCallback(process_response)
99         return deferred

转载于:https://www.cnblogs.com/guozepingboke/p/10774181.html

Downloader Middleware相关推荐

  1. Scrapy 下载器 中间件(Downloader Middleware)

    Scrapy 下载器中间件官方文档:https://scrapy-chs.readthedocs.io/zh_CN/1.0/topics/downloader-middleware.html 官方 英 ...

  2. Scrapy 2.6 Downloader Middleware 下载器中间件使用指南

    Python3 的 Scrapy 爬虫框架 中数据爬取过程中的下载器中间件是一个挂钩 Scrapy 的请求/响应处理的框架.是一个轻量级的低级系统并且应用于全局更改 Scrapy 的请求和响应. 其主 ...

  3. scrapy下载中间件(downloader middleware)和蜘蛛中间件(spider middleware)

    scrapy组件 首先我们看下scrapy官网提供的新结构图,乍一看这画的是啥啊,这需要你慢慢的理解其原理就很容易看懂了,这些都是一个通用爬虫框架该具有的一些基本组件.上一篇博客说了项目管道(也就是图 ...

  4. python中scrapy的middleware是干嘛的_python爬虫常用之Scrapy 中间件

    一.概述 1.中间件的作用 在scrapy运行的整个过程中,对scrapy框架运行的某些步骤做一些适配自己项目的动作. 例如scrapy内置的HttpErrorMiddleware,可以在http请求 ...

  5. 第44讲:scrapy中间键Middleware的使用

    我们在 Scrapy 架构中,可以看到有一个叫作 Middleware 的概念,中文翻译过来就叫作中间件,在 Scrapy 中有两种 Middleware,一种是 Spider Middleware, ...

  6. python中scrapy的middleware是干嘛的_Python之爬虫(十九) Scrapy框架中Download Middleware用法...

    这篇文章中写了常用的下载中间件的用法和例子. Downloader Middleware处理的过程主要在调度器发送requests请求的时候以及网页将response结果返回给spiders的时候,所 ...

  7. python pipeline框架_爬虫(十六):Scrapy框架(三) Spider Middleware、Item Pipeline|python基础教程|python入门|python教程...

    https://www.xin3721.com/eschool/pythonxin3721/ 1. Spider Middleware Spider Middleware是介入到Scrapy的Spid ...

  8. Scrapy爬虫框架第五讲(linux环境)【download middleware用法】

    DOWNLOAD MIDDLEWRE用法详解 通过上面的Scrapy工作架构我们对其功能进行下总结: (1).在Scheduler调度出队列时的Request送给downloader下载前对其进行修改 ...

  9. Scrapy框架的概念、作用和工作流程

    1. scrapy的概念         Scrapy是一个Python编写的开源网络爬虫框架.它是一个被设计用于爬取网络数据.提取结构性数据的框架. Scrapy是一个为了爬取网站数据,提取结构性数 ...

最新文章

  1. HTML中常见的各种位置距离以及dom中的坐标讨论
  2. 给PHPSTORM添加XDEBUG调试功能
  3. Ghost XP基本介绍
  4. gedit乱码 fedora
  5. C# 模拟一个处理消息队列的线程类 Message Queue
  6. Android 自定义 ListView 显示网络上 JSON 格式歌曲列表
  7. 【一鸣离职,左晖去世】互联网老兵给大家的三个建议
  8. Linux用户和用户组和文件权限介绍
  9. Spring中采用公共变量并发问题解决
  10. 用 Javascript 验证表单(form)中多选框(checkbox)值
  11. 7. JavaScript RegExp 对象
  12. 破解烽火移动HG6201M 破解 超级密码
  13. 桌面计算机怎么设置声音,右下角小喇叭不见了-电脑桌面右下角有一个调整声音的小喇叭图标没 – 手机爱问...
  14. 免安装版的Mysql安装与配置——详细教程
  15. 弘扬时代新风建设网络文明,小趣带你揭秘肾透明细胞癌致瘤机制
  16. Edge、Chrome自定义新标签页网址
  17. 计算机主机启动 显示器不动什么原因,主机开了电脑屏幕不亮怎么回事?电脑开机后显示器不亮的解决方案...
  18. 单片机学习笔记9--常见的通信方式(基于百问网STM32F103系列教程)
  19. HTML的meta标签
  20. Hyperledger Fabric共识机制

热门文章

  1. winXP环境下将Python脚本生成EXE可执行文件
  2. 思维导图从入门到大神
  3. python circle函数如何画圆_Python练习实例56 | 画图,学用circle画圆形
  4. cloud flare
  5. php 微信表情 转码和解码方法
  6. FILE *与FD的区别
  7. 第十五章 数据访问部件的应用及编程(一)
  8. Brats 脑肿瘤分割hausdroff95计算
  9. MSP430F5529实现LED1无极调光
  10. 《中国历代政治得与失》读书笔记