Scrapy源码解析:DownloadHandlers设计与解析
1、源码解析
代码路径:scrapy/core/downloader/__init__.py
详细代码解析,请看代码注释
"""Download handlers for different schemes"""import logging
from typing import TYPE_CHECKING, Any, Callable, Dict, Generator, Union, castfrom twisted.internet import defer
from twisted.internet.defer import Deferredfrom scrapy import Request, Spider, signals
from scrapy.exceptions import NotConfigured, NotSupported
from scrapy.utils.httpobj import urlparse_cached
from scrapy.utils.misc import create_instance, load_object
from scrapy.utils.python import without_none_valuesif TYPE_CHECKING:from scrapy.crawler import Crawlerlogger = logging.getLogger(__name__)class DownloadHandlers:def __init__(self, crawler: "Crawler"):self._crawler: "Crawler" = crawlerself._schemes: Dict[str, Union[str, Callable]] = {} # self._schemes 用于存放协议:协议处理器路径的字典,注意是协议处理器的路径,还没有实例化这个协议处理器。self._handlers: Dict[str, Any] = {} # stores instanced handlers for schemes 用于存放各个协议的下载器的实例self._notconfigured: Dict[str, str] = {} # remembers failed handlers # 记录不在设置中设置的协议handlers: Dict[str, Union[str, Callable]] = without_none_values(crawler.settings.getwithbase("DOWNLOAD_HANDLERS") # 读取配置中,设置的什么协议用什么下载器)for scheme, clspath in handlers.items():self._schemes[scheme] = clspath # 把协议:协议处理器存入self._schemesself._load_handler(scheme, skip_lazy=True)# 在这个循环里就加载了大部分协议下载器。只有s3没有被加载。在调用self._load_handler的时候# 这里传的skip_lazy为True,在self._load_handler内部需要与各个协议下载器中的lazy属性结合判断,最终决定要不要加载crawler.signals.connect(self._close, signals.engine_stopped)def _get_handler(self, scheme: str) -> Any: # 就是根据协议名,获取对应的下载器实例"""Lazy-load the downloadhandler for a schemeonly on the first request for that scheme."""if scheme in self._handlers: # 如果已经取过对应协议的处理器了,就直接返回该处理器return self._handlers[scheme]if scheme in self._notconfigured: # 如果是已知的未配置的协议,就直接返回Nonereturn Noneif scheme not in self._schemes:self._notconfigured[scheme] = "no handler available for that scheme" # 第一次出现一个未配置下载器的协议的时候,记录一下这个协议return Nonereturn self._load_handler(scheme)def _load_handler(self, scheme: str, skip_lazy: bool = False) -> Any: # 根据协议名,实例化下载器path = self._schemes[scheme]try:dhcls = load_object(path) # 加载下载器类if skip_lazy and getattr(dhcls, "lazy", True): # 判断要不要惰性加载return Nonedh = create_instance( # 实例化协议下载器objcls=dhcls,settings=self._crawler.settings,crawler=self._crawler,)except NotConfigured as ex:self._notconfigured[scheme] = str(ex)return Noneexcept Exception as ex:logger.error('Loading "%(clspath)s" for scheme "%(scheme)s"',{"clspath": path, "scheme": scheme},exc_info=True,extra={"crawler": self._crawler},)self._notconfigured[scheme] = str(ex)return Noneelse:self._handlers[scheme] = dhreturn dhdef download_request(self, request: Request, spider: Spider) -> Deferred: # 从request中取出协议,然后取出下载器,下载scheme = urlparse_cached(request).schemehandler = self._get_handler(scheme)if not handler:raise NotSupported(f"Unsupported URL scheme '{scheme}': {self._notconfigured[scheme]}")return cast(Deferred, handler.download_request(request, spider))@defer.inlineCallbacksdef _close(self, *_a: Any, **_kw: Any) -> Generator[Deferred, Any, None]: # 当收到引擎的engine_stopped的信号的时候,挨个的停止各个协议的下载器for dh in self._handlers.values():if hasattr(dh, "close"):yield dh.close()
2、文件解析
可以把DownloadHandlers理解成各个协议下载器的处理器。用来加载各个协议对应的下载器的处理器。下图可以看出scrapy默认提供了data、file、ftp、http、s3协议的下载器。

3、结构示意图

相关文章:
Scrapy源码解析:DownloadHandlers设计与解析
1、源码解析 代码路径:scrapy/core/downloader/__init__.py 详细代码解析,请看代码注释 """Download handlers for different schemes"""import logging from typing import TYPE_CHECKING, Any, Callable, Dict, Gener…...
shell基础-awk
awk 是一个强大的文本处理工具,广泛用于 Unix 和 Linux 系统中。它可以用来处理和分析文本文件,特别是那些包含结构化数据的文件。以下是 awk 的基础知识和一些常用示例。 基本概念 记录和字段: 记录:awk 处理的每一行文本称为一…...
@Controller 和 @RestController 区别
功能范畴: Controller:用于定义一个控制器类,主要用于处理用户请求并返回视图(通常是HTML页面)。常常与 Spring MVC 的视图解析器一起使用。RestController:是一个特殊类型的控制器,用于返回数据而不是视图…...
【数据库设计】规范设计理论之数据依赖的公理系统(1)
知道范式的几种分类之后还并不能帮助我们设计一款好的数据库,在对关系进行拆解(指模式分解)之前,我们需要引入一个理论基础让设计过程变得有迹可循和具备一定的严谨性以此来支撑数据库背后的可靠性。 Armstrong公理系统 所谓公理…...
Leetcode 合并两个数组
算法思想是双指针从后往前合并,利用了 nums1 数组的尾部空间来存储合并后的结果,从而避免了额外空间的使用。具体步骤如下: 初始化指针: i 指向 nums1 的有效元素末尾,即位置 m - 1。j 指向 nums2 的末尾,即…...
Native Crash 信号速查
重点信号 SIGSEGV(11) signal segmentation violation:段错误无效内存访问访问无权访问的内存空指针、越界访问(mmap?) SIGBUS(7) Bus Error:总线错误非法内存访问访问 …...
【工具变量】自由贸易试验区试点DID数据集(2003-2023年)
数据简介:自由贸易试验区(Free Trade Zone,简称FTZ)是中国ZF在新形势下为了推进GG开放、提高开放型经济水平而采取的重要战略举措。自贸试验区在一国的部分领土内运入任何货物,被认为在关境以外,免于实施惯…...
js-在数组中根据name查找出对应id(find与filter方法)
1.根据name查找出对应id 使用数组的 find 方法来根据对象的某个属性(如名称)查找对应的对象,并获取该对象的 id 属性。 2.find 方法 const array [ { id: 1, name: Alice }, { id: 2, name: Bob }, { id: 3, name: Charlie } ]; 使用…...
推荐:自然语言处理方向的一些创新点
以下是自然语言处理研究方向的一些创新点: 一、预训练模型的改进与优化 模型架构创新 融合多模态信息: 传统的自然语言处理模型主要处理文本信息。创新点在于将图像、音频等多模态信息融合到预训练模型中。例如,对于描述一幅画的文本&#x…...
成都睿明智科技有限公司抖音电商服务的领航者
在这个短视频风起云涌的时代,抖音电商以其独特的魅力迅速崛起,成为无数商家争夺流量与销量的新战场。在这片红海之中,如何脱颖而出,实现销售额的飞跃?今天,就让我们一同走进成都睿明智科技有限公司…...
【大数据学习 | kafka】kafka的整体框架与数据结构
1. kafka的整体框架 首先kafka启动以后所有的broker都会向zookeeper进行注册,在/brokers/ids中以列表的形式展示所有的节点,在/controller节点中使用独享锁实现broker的选举,其中一个机器为主节点。其他的为从节点,选举的根本原则…...
隐私保护下的数据提取策略
在隐私保护下进行数据提取,需要采取一系列策略来确保个人隐私得到妥善保护,同时满足数据使用的需求。以下是一些关键的策略和方法: 一、数据最小化原则 定义:仅收集和提取必要的数据,避免收集过多的个人信息或不相关…...
vue 和 django 报 CORS(跨域资源共享,Cross-Origin Resource Sharing)是一种跨域访问的机制,
在使用 Vue 和 Django 进行前后端分离开发时,如果遇到 AxiosError: Network Error 的错误,通常可能是由于以下几种原因引起的。下面列出了一些常见的原因和解决方案。 1. CORS(跨源资源共享)问题 当你的 Vue 应用和 Django 后端…...
「Mac畅玩鸿蒙与硬件3」鸿蒙开发环境配置篇3 - DevEco Studio 插件安装与配置
本篇将专注于如何在 DevEco Studio 中安装和配置必要的插件,以增强开发功能和提升效率。通过正确配置插件,开发流程能够得到简化,开发体验也会更加顺畅。 关键词 插件安装配置优化DevEco Studio开发工具 一、插件的重要性 插件可以大幅扩展…...
【论文阅读】PGAN
1. WHY 问题 图像超分辨率一直是一个热门研究课题,具有重要的应用价值。基于生成对抗网络GAN的单幅图像超分辨率方法显示重建图像与人类视觉特征更一致。因此,基于 GAN 的网络优化已成为图像超分辨率的主流。然而,一些最新研究表明…...
基于Unet卷积神经网络的脑肿瘤MRI分割
项目源码获取方式见文章末尾! 回复暗号:13,免费获取600多个深度学习项目资料,快来加入社群一起学习吧。 《------往期经典推荐------》 项目名称 1.【YOLO模型实现农作物病虫害虫识别带GUI界面】 2.【卫星图像道路检测DeepLabV3P…...
[java][基础]HTTPTomcatServlet
1,Web概述 1.1 Web和JavaWeb的概念 Web是全球广域网,也称为万维网(www),能够通过浏览器访问的网站。 在我们日常的生活中,经常会使用浏览器去访问百度、京东、传智官网等这些网站,这些网站统称为Web网站。如下就是通…...
【开源免费】基于SpringBoot+Vue.JS网上超市系统(JAVA毕业设计)
本文项目编号 T 037 ,文末自助获取源码 \color{red}{T037,文末自助获取源码} T037,文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析 六、核心代码6.1 查…...
【单片机】深入剖析USART与UART的区别
在嵌入式系统和微控制器开发中,串行通信是一个非常关键的概念,涉及到不同设备之间的数据传输。常见的串行通信协议包括UART(Universal Asynchronous Receiver/Transmitter)和USART(Universal Synchronous/Asynchronous…...
Linux tac命令
Linux tac命令是一个用于逆序显示文件内容的工具,其名称来源于“cat”的反向拼写。tac命令的基本功能是将文件的内容从最后一行开始输出,直到第一行结束,这与cat命令的功能相反,cat命令是从第一行开始输出直到最后一行。 tac…...
第19节 Node.js Express 框架
Express 是一个为Node.js设计的web开发框架,它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用,和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...
iOS 26 携众系统重磅更新,但“苹果智能”仍与国行无缘
美国西海岸的夏天,再次被苹果点燃。一年一度的全球开发者大会 WWDC25 如期而至,这不仅是开发者的盛宴,更是全球数亿苹果用户翘首以盼的科技春晚。今年,苹果依旧为我们带来了全家桶式的系统更新,包括 iOS 26、iPadOS 26…...
MongoDB学习和应用(高效的非关系型数据库)
一丶 MongoDB简介 对于社交类软件的功能,我们需要对它的功能特点进行分析: 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具: mysql:关系型数据库&am…...
postgresql|数据库|只读用户的创建和删除(备忘)
CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...
3403. 从盒子中找出字典序最大的字符串 I
3403. 从盒子中找出字典序最大的字符串 I 题目链接:3403. 从盒子中找出字典序最大的字符串 I 代码如下: class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...
Element Plus 表单(el-form)中关于正整数输入的校验规则
目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入(联动)2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...
Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)
在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马(服务器方面的)的原理,连接,以及各种木马及连接工具的分享 文件木马:https://w…...
Xen Server服务器释放磁盘空间
disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...
NPOI Excel用OLE对象的形式插入文件附件以及插入图片
static void Main(string[] args) {XlsWithObjData();Console.WriteLine("输出完成"); }static void XlsWithObjData() {// 创建工作簿和单元格,只有HSSFWorkbook,XSSFWorkbook不可以HSSFWorkbook workbook new HSSFWorkbook();HSSFSheet sheet (HSSFSheet)workboo…...
day36-多路IO复用
一、基本概念 (服务器多客户端模型) 定义:单线程或单进程同时监测若干个文件描述符是否可以执行IO操作的能力 作用:应用程序通常需要处理来自多条事件流中的事件,比如我现在用的电脑,需要同时处理键盘鼠标…...
