Scrapy:任务队列底层设计详解
Scrapy 中队列设计详解
1. 概述
Scrapy 的队列系统是其调度器(Scheduler)的核心组件之一,负责存储和管理待抓取的请求。Scrapy 实现了两种类型的队列:
- 内存队列:请求存储在内存中,重启后数据丢失
- 磁盘队列:请求序列化到磁盘,支持持久化存储
文件路径:/scrapy/squeues.py
设计模式:装饰器模式与Python中的装饰器
2. 队列的基本架构
2.1 队列类型
Scrapy 在 squeues.py
中定义了以下几种队列:
-
磁盘队列(使用 pickle 序列化):
PickleFifoDiskQueue
: 先进先出磁盘队列PickleLifoDiskQueue
: 后进先出磁盘队列(默认的磁盘队列类)
-
磁盘队列(使用 marshal 序列化):
MarshalFifoDiskQueue
: 先进先出磁盘队列MarshalLifoDiskQueue
: 后进先出磁盘队列
-
内存队列:
FifoMemoryQueue
: 先进先出内存队列LifoMemoryQueue
: 后进先出内存队列(默认的内存队列类)
2.2 核心设计模式
Scrapy 的队列设计采用了装饰器模式,主要包含以下几个层次:
- 基础队列装饰:
def _with_mkdir(queue_class):class DirectoriesCreated(queue_class):def __init__(self, path, *args, **kwargs):dirname = Path(path).parentif not dirname.exists():dirname.mkdir(parents=True, exist_ok=True)super().__init__(path, *args, **kwargs)return DirectoriesCreated
- 序列化装饰:
def _serializable_queue(queue_class, serialize, deserialize):class SerializableQueue(queue_class):def push(self, obj):s = serialize(obj)super().push(s)def pop(self):s = super().pop()if s:return deserialize(s)return Nonedef peek(self):try:s = super().peek()except AttributeError as ex:raise NotImplementedError("The underlying queue class does not implement 'peek'") from exif s:return deserialize(s)return Nonereturn SerializableQueue
3. 序列化实现
3.1 Pickle 序列化队列
Scrapy 使用 pickle 作为默认的序列化方案,实现如下:
def _pickle_serialize(obj):try:return pickle.dumps(obj, protocol=4)except (pickle.PicklingError, AttributeError, TypeError) as e:raise ValueError(str(e)) from e# 创建 pickle 序列化的磁盘队列
_PickleFifoSerializationDiskQueue = _serializable_queue(_with_mkdir(queue.FifoDiskQueue), _pickle_serialize, pickle.loads
)_PickleLifoSerializationDiskQueue = _serializable_queue(_with_mkdir(queue.LifoDiskQueue), _pickle_serialize, pickle.loads
)
3.2 Marshal 序列化队列
Marshal 作为备选的序列化方案,实现如下:
# 创建 marshal 序列化的磁盘队列
_MarshalFifoSerializationDiskQueue = _serializable_queue(_with_mkdir(queue.FifoDiskQueue), marshal.dumps, marshal.loads
)_MarshalLifoSerializationDiskQueue = _serializable_queue(_with_mkdir(queue.LifoDiskQueue), marshal.dumps, marshal.loads
)
4. 序列化方案对比
4.1 Pickle vs Marshal 在 Scrapy 中的应用
-
Pickle 的优势:
- 支持更多的 Python 数据类型
- 可以序列化自定义类和对象
- 支持对象引用和循环引用
- 版本兼容性更好
-
Marshal 的优势:
- 序列化速度更快
- 内存占用更少
- 实现更简单,安全性较高
4.2 为什么提供两种序列化方案?
-
性能考虑:
- Marshal 序列化速度快,适合简单数据结构
- Pickle 功能更强大,适合复杂对象
-
兼容性考虑:
- Pickle 支持自定义类的序列化
- Marshal 只支持基本数据类型
-
安全性考虑:
- Marshal 更安全,不支持代码执行
- Pickle 需要注意安全风险
5. 队列的实际应用
5.1 在调度器中的使用
# 在 settings.py 中配置队列类型
SCHEDULER_DISK_QUEUE = "scrapy.squeues.PickleLifoDiskQueue"
SCHEDULER_MEMORY_QUEUE = "scrapy.squeues.LifoMemoryQueue"
5.2 队列选择策略
- 请求入队逻辑:
def enqueue_request(self, request):if not request.dont_filter and self.df.request_seen(request):return Falsedqok = self._dqpush(request) # 优先尝试放入磁盘队列if dqok:self.stats.inc_value("scheduler/enqueued/disk")else:self._mqpush(request) # 磁盘队列失败则放入内存队列self.stats.inc_value("scheduler/enqueued/memory")return True
- 请求出队逻辑:
def next_request(self):request = self.mqs.pop() # 优先从内存队列获取if request:self.stats.inc_value("scheduler/dequeued/memory")else:request = self._dqpop() # 内存队列为空则从磁盘队列获取if request:self.stats.inc_value("scheduler/dequeued/disk")return request
6. 最佳实践
-
队列类型选择:
- 小规模爬虫:使用内存队列即可
- 大规模爬虫:使用磁盘队列保证可靠性
- 需要暂停恢复:必须使用磁盘队列
-
序列化方案选择:
- 简单请求:可以使用 Marshal 序列化
- 复杂请求:建议使用 Pickle 序列化
- 注重性能:选择 Marshal
- 注重功能:选择 Pickle
-
性能优化:
- 合理设置并发数
- 适当调整队列类型
- 根据数据复杂度选择序列化方案
7. 注意事项
-
安全性:
- 使用 Pickle 时注意反序列化安全
- 不要处理不信任来源的序列化数据
-
性能:
- 磁盘队列会带来 I/O 开销
- 序列化/反序列化会消耗 CPU
-
可靠性:
- 定期备份磁盘队列数据
- 处理序列化异常
- 考虑磁盘空间限制
相关文章:
Scrapy:任务队列底层设计详解
Scrapy 中队列设计详解 1. 概述 Scrapy 的队列系统是其调度器(Scheduler)的核心组件之一,负责存储和管理待抓取的请求。Scrapy 实现了两种类型的队列: 内存队列:请求存储在内存中,重启后数据丢失磁盘队列…...
zola + github page,用 workflows 部署
之前的Zola都是本地build之后,再push到github上,这种方式很明显的弊端就是只能在本地编辑,而不能通过github编辑,再pull到本地,缺乏了灵活性。因此将zola用workflows来部署。 repo地址:https://github.com/…...
pytest测试专题 - 1.2 如何获得美观的测试报告
<< 返回目录 1 pytest测试专题 - 1.2 如何获得美观的测试报告 1.1 背景 虽然pytest命令的报文很详细,用例在执行调试时还算比较方便阅读和提取失败信息, 但对于大量测试用例运行时,可能会存在以下不足 报文被冲掉测试日志没法归档 …...
关闭浏览器安全dns解决访问速度慢的问题
谷歌浏览器加载速度突然变慢了?检查安全DNS功能(DoH)是否被默认开启。 谷歌浏览器在去年已经推出安全DNS功能(即DoH) , 启用此功能后可以通过加密的DNS增强网络连接安全性。例如查询请求被加密后网络运营商将无法嗅探用户访问的地址,因此对于增强用户的…...
今日AI和商界事件(2025-02-14)
今日AI大事件主要包括以下几个方面: 一、苹果新品预告 事件概述:苹果CEO蒂姆库克在社交媒体发布7秒视频,配文“准备好迎接家庭的新成员”,并宣布2月19日将有新品发布。知名科技记者马克古尔曼称,新款低端iPhone SE将…...
【黑马点评优化】1-使用JWT登录认证+redis实现自动续期
1-使用JWT登录认证redis实现自动续期 0 前言1 原先的redis实现登录鉴权2 JWT登录认证Redis自动续期2.1 认证(identification)授权 (authorization)和鉴权(Authorization)2.1.1 认证(identificat…...
一个让Stable Diffusion更稳定、更易用的Github开源项目
2023除了ChatGPT大火,Stable Diffusion同样也是非常火热,Stable Diffusion是一个Github开源项目,很多爱好者都会本地安装,但面对一些初学者来说,在安装、配置和使用过程中还是会经常出现很多问题,特别不了解…...
Mac之JDK安装
Mac之JDK安装 一.安装 jdk 打开终端输入命令:java -version 查看是否已安装 JDK Oracle 官方下载地址 根据自己Mac 系统安装 查看 Mac 系统,打开中断命令,输入: uname -a Compressed Archive 是压缩文档,下载的是一个 .tar.gz 压缩包 D…...
深入Flask:如何优雅地处理HTTP请求与响应
哈喽,大家好,我是木头左! 本文将带你深入了解如何在Flask中优雅地处理HTTP请求和响应,让你的应用更加高效、安全和用户友好。 创建一个简单的Flask应用 让从创建一个最简单的Flask应用开始: from flask import Flaskapp = Flask(__name__)@app.route(/) def...
kron积计算mask类别矩阵
文章目录 1. 生成类别矩阵如下2. pytorch 代码3. 循环移动矩阵 1. 生成类别矩阵如下 2. pytorch 代码 import torch import torch.nn as nn import torch.nn.functional as Ftorch.set_printoptions(precision3, sci_modeFalse)if __name__ "__main__":run_code 0…...
Redis实现消息队列
什么是消息列队。 消息队列是一种应用间的异步协作机制,同时消息队列中间件是分布式系统中重要的组件,主要解决应用耦合,异步消息,流量削峰等问题。实现高性能,高可用,可伸缩和最终一致性架构。市面上的 M…...
vue+springboot+webtrc+websocket实现双人音视频通话会议
前言 最近一些时间我有研究,如何实现一个视频会议功能,但是找了好多资料都不太理想,最终参考了一个文章 WebRTC实现双端音视频聊天(Vue3 SpringBoot) 只不过,它的实现效果里面只会播放本地的mp4视频文件&…...
【免费送书活动】《MySQL 9从入门到性能优化(视频教学版)》
本博主免费赠送读者3本书,书名为《MySQL 9从入门到性能优化(视频教学版)》。 《MySQL 9从入门到性能优化(视频教学版)(数据库技术丛书)》(王英英)【摘要 书评 试读】- 京东图书 这本书已经公开…...
【设计模式】【行为型模式】命令模式(Command)
👋hi,我不是一名外包公司的员工,也不会偷吃茶水间的零食,我的梦想是能写高端CRUD 🔥 2025本人正在沉淀中… 博客更新速度 👍 欢迎点赞、收藏、关注,跟上我的更新节奏 🎵 当你的天空突…...
1.14学习总结
日常刷题单 刷了题目后,对于排序方法更加熟练,手搓代码的速度也得到了提高。 感觉字符串还不熟练,高精度更是云里雾里,上升空间极大。 同时看见今晚有个入门难度的测试,去练了练手,想看看自己是什么成分&…...
QxOrm生成json
下载Qxorm-1.5版本 使用vs打开项目,直接生成即可: lib目录中会生成dll和lib文件 新建Qt项目使用Qxorm: 将QxOrm中上面三个目录拷贝到新建的Qt项目中 pro文件添加使用QxOrm第三方库 INCLUDEPATH $$PWD/include/ LIBS -L"$$PWD/lib" LIBS…...
伯克利 CS61A 课堂笔记 09 —— Data Abstraction
本系列为加州伯克利大学著名 Python 基础课程 CS61A 的课堂笔记整理,全英文内容,文末附词汇解释。 目录 01 Data Abstraction 数据抽象 Ⅰ Rational Numbers Ⅱ Rational Number Arithmetic 02 Pairs 对 Ⅰ Representing Pairs Using Lists Ⅱ Re…...
高频 SQL 50 题(基础版)
高频 SQL 50 题(基础版) 查询连接聚合函数排序和分组高级查询和连接子查询高级字符串函数 / 正则表达式 / 子句 查询 链接: link 链接: link 链接: link 链接: link 链接: link 连接 链接: 高频 SQL 50 题基础版_1378. 使用唯一标识码替换员工ID 链接…...
HtmlRAG:RAG系统中,HTML比纯文本效果更好
HtmlRAG 方法通过使用 HTML 而不是纯文本来增强 RAG 系统中的知识表示能力。通过 HTML 清洗和两步块树修剪方法,在保持关键信息的同时缩短了 HTML 文档的长度。这种方法优于现有基于纯文本的RAG的性能。 方法 其实主要看下围绕html提纯思路,将提纯后的…...
python学opencv|读取图像(六十二)使用cv2.morphologyEx()形态学函数实现图像梯度处理
【1】引言 前序已经学习了腐蚀和膨胀的单独作用函数,还研究了按照不同顺序调用腐蚀和膨胀函数调整图像效果,相关文章包括且不限于: python学opencv|读取图像(六十一)先后使用cv2.dilate()函数和cv2.erode()函数实现图…...
10G EPON光模块
一、10G EPON对称光模块 工作模式:上行突发接收、下行连续发射。 工作原理:当需要发送信号时,系统信号通过光模块的电接口把信号传送到驱动芯片,芯片处理后,驱动激光器发出调制光信号,经光纤发到远端&…...
RocketMQ与kafka如何解决消息丢失问题?
0 前言 消息丢失基本是分布式MQ中需要解决问题,消息丢失时保证数据可靠性的范畴。如何保证消息不丢失程序员面试中几乎不可避免的问题。本文主要说明RocketMQ和Kafka在解决消息丢失问题时,在生产者、Broker和消费者之间如何解决消息丢失问题。 1.Rocket…...
每日Attention学习23——KAN-Block
模块出处 [SPL 25] [link] [code] KAN See In the Dark 模块名称 Kolmogorov-Arnold Network Block (KAN-Block) 模块作用 用于vision的KAN结构 模块结构 模块代码 import torch import torch.nn as nn import torch.nn.functional as F import mathclass Swish(nn.Module)…...
【前端】ES6新特性汇总
本文作者: slience_me ES6新特性汇总 1. let声明变量 1)let作用域 // var 声明的变量往往会越域 // let 声明的变量有严格的局部作用域 {var a 1;let b 2; } console.log(a); // 1 console.log(b); // 报错 b is not defined2)声明次数 …...
2024 CyberHost 语音+图像-视频
项目:CyberHost: Taming Audio-driven Avatar Diffusion Model with Region Codebook Attention 音频驱动的身体动画面临两个主要挑战:(1)关键人体部位,如面部和手部,在视频帧中所占比例较小&#x…...
Git命令摘录
使用 Git 升级软件通常是指通过 Git 仓库获取软件的最新版本或更新代码。以下是详细的步骤和方法: 1. 克隆软件仓库 如果这是你第一次获取软件代码,可以使用 git clone 命令将远程仓库克隆到本地。 git clone <仓库地址> 例如: git cl…...
DeepSeek24小时写作机器人,持续创作高质量文案
内容创作已成为企业、自媒体和创作者的核心竞争力。面对海量的内容需求,人工创作效率低、成本高、质量参差不齐等问题日益凸显。如何在有限时间内产出高质量内容?DeepSeek写作机器人,一款24小时持续创作的智能工具,为企业和个人提…...
Python 面向对象的三大特征
前言:本篇讲解面向对象的三大特征(封装,继承,多态),还有比较细致的(类属性类方法,静态方法),分步骤讲解,比较适合理清楚三大特征的思路 面向对象的…...
在mac中安装Colima使用docker(替代Docker Desktop)
目录 推荐方案:Colima Docker CLI(原生 ARM 支持) 步骤 1: 安装必需工具 步骤 2: 启动 Colima (优化 ARM 虚拟机) 步骤 3: 绑定 Docker CLI 到 Colima 步骤 4: 验证 Docker 运行 方案对比与注意事项 常见陷阱 卸载残留配置ÿ…...
YOLO11网络结构以及改进1
YOLO11 1.YOLO11网络结构图在哪里?2.对应的网络结构图3.每一个模块详解3.1 Conv模块3.2关于卷积模块3.3 关于给各个模块指定参数的细节 4.加入CBAM 1.YOLO11网络结构图在哪里? 2.对应的网络结构图 3.每一个模块详解 3.1 Conv模块 位置:ultr…...
EtherNetIP转ModbusTCP网关,给风电注入“超级赛亚人”能量
EtherNetIP转ModbusTCP网关,给风电注入“超级赛亚人”能量 在工业通信领域,常常需要将不同网络协议的设备和系统连接起来,以实现更高效的数据交互和系统集成。比如,把EtherNet/IP设备及其网络连接到ModbusTCP网络系统,…...
30天开发操作系统 第 20 天 -- API
前言 大家早上好,今天我们继续努力哦。 昨天我们已经实现了应用程序的运行, 今天我们来实现由应用程序对操作系统功能的调用(即API, 也叫系统调用)。 为什么这样的功能称为“系统调用”(system call)呢?因为它是由应用程序来调用(操作)系统中的功能来完…...
DeepSeek处理自有业务的案例:让AI给你写一份小众编辑器(EverEdit)的语法着色文件
1 DeepSeek处理自有业务的案例:让AI给你写一份小众编辑器(EverEdit)的语法着色文件 1.1 背景 AI能力再强,如果不能在企业的自有业务上产生助益,那基本也是一无是处。将企业的自有业务上传到线上训练,那是脑子进水的做法ÿ…...
在香橙派5 NPU上使用Yolov5
【香橙派】使用NPU部署Yolov5的完整解决方案 香橙派使用NPU部署Yolov5的完整解决方案 Orangepi 5 Pro(香橙派5pro)部署yolov5 RK3588实战:调用npu加速,yolov5识别图像、ffmpeg发送到rtmp服务器 香橙派5 RK3588 yolov5模型转换rknn及部署踩坑全记录 orang…...
常用排序算法
1. 基础排序算法 1.1 冒泡排序(Bubble Sort) 原理: 依次比较相邻元素,将较大的元素逐步"冒泡"到右侧。 def bubble_sort(arr):n len(arr)for i in range(n):swapped Falsefor j in range(0, n-i-1):if arr[j] >…...
MySQL判空函数--IFNULL函数的使用
文章目录 IFNULL函数介绍IFNULL函数的语法举例相关扩展 IFNULL函数介绍 在MySQL中,IFNULL函数用于判断给定的表达式是否为NULL。如果表达式为NULL,则IFNULL函数返回指定的替代值;如果表达式不为NULL,则返回表达式本身的值。 IFN…...
Git 设置代理
设置 HTTP 和 HTTPS 代理 运行以下命令来配置 Git 的 HTTP 和 HTTPS 代理: git config --global http.proxy http://127.0.0.1:7890 git config --global https.proxy https://127.0.0.1:7890 验证代理设置 你可以通过以下命令检查代理是否设置成功: g…...
nsc account 及user管理
从安全角度,推荐使用sign 模式进行nats account及用户管理 把权限放到account level 用户密码泄露可以通过快速更换用户可以设置过期日期,进行安全轮换 此外通过nsc 管理用户和权限,可以统一实现全局管控,包括subject管控&#…...
llama.cpp部署 DeepSeek-R1 模型
一、llama.cpp 介绍 使用纯 C/C推理 Meta 的LLaMA模型(及其他模型)。主要目标llama.cpp是在各种硬件(本地和云端)上以最少的设置和最先进的性能实现 LLM 推理。纯 C/C 实现,无任何依赖项Apple 芯片是一流的——通过 A…...
NO.18十六届蓝桥杯备战|循环嵌套|乘法表|斐波那契|质数|水仙花数|(C++)
循环嵌套 循环嵌套的使⽤ while , do while , for ,这三种循环往往会嵌套在⼀起才能更好的解决问题,就是我们所说的:循环嵌套。这三种循环都可以任意嵌套使⽤ ⽐如: 写⼀个代码,打印⼀个乘法⼝…...
用什么办法能实现ubuntu里面运行的自己开发的python程序能自动升级。
要实现Ubuntu中自己开发的Python程序自动升级,可以通过以下几种方式: 1. 使用 Git 仓库 定时任务 如果你的Python程序托管在Git仓库中,可以通过定时拉取最新代码来实现自动升级。 步骤: 确保Python程序在Git仓库中。在Ubuntu上…...
org.apache.kafka.common.errors.TimeoutException
个人博客地址:org.apache.kafka.common.errors.TimeoutException | 一张假钞的真实世界 使用kafka-console-producer.sh向远端Kafka写入数据时遇到以下错误: $ bin/kafka-console-producer.sh --broker-list 172.16.72.202:9092 --topic test This is …...
【AI实践】deepseek支持升级git
当前Windows 11 WSL的git是2.17,Android Studio提示需要升级到2.19版本 网上找到指导文章 安装git 2.19.2 cd /usr/src wget https://www.kernel.org/pub/software/scm/git/git-2.19.2.tar.gz tar xzf git-2.19.2.tar.gz cd git-2.19.2 make prefix/usr/l…...
IntelliJ IDEA 2024.1.4版无Tomcat配置
IntelliJ IDEA 2024.1.4 (Ultimate Edition) 安装完成后,调试项目发现找不到Tomcat服务: 按照常规操作添加,发现服务插件中没有Tomcat。。。 解决方法 1、找到IDE设置窗口 2、点击Plugins按钮,进入插件窗口,搜索T…...
利用Firewalld和Iptables实现IP端口限制与开放
这里写目录标题 前言一、FirewalldIP端口限制1.1 确认启动状态1.2 启动Firewalld1.3 查看当前连接到Nacos的IP1.4 添加访问规则1.5 重新加载配置1.6 查看当前活动的规则列表1.7 移除某个规则 二、Firewalld 开放端口2.1 开放 6379端口2.2 重新加载防火墙2.3 验证规则 三、Iptab…...
两步在 Vite 中配置 Tailwindcss
第一步:安装依赖 npm i -D tailwindcss tailwindcss/vite第二步:引入 tailwindcss 更改配置 // src/main.js import tailwindcss/index// vite.config.js import vue from vitejs/plugin-vue import tailwindcss from tailwindcss/viteexport default …...
单片机原理与运用
个人主页:java之路-CSDN博客(期待您的关注) 目录 一、走进单片机的世界 二、单片机是什么 (一)定义与本质 (二)与普通计算机的区别 三、单片机的工作原理深度剖析 (一)硬件组成及功能 &am…...
MYSQL-数据恢复与备份
个人主页:java之路-CSDN博客(期待您的关注) 目录 数据的重要性与备份恢复的意义 MySQL 备份大揭秘 备份类型大盘点 备份工具展示台 备份实操全流程 MySQL 恢复大作战 恢复原理深剖析 恢复方法大集合 实战案例大放送 备份与恢复的最佳实践 备份策略制定法 …...
【Java】实现后端请求接口
【Java】实现后端请求接口 【一】使用 HttpURLConnection 实现四种请求方式的示例【1】Get请求【2】POST请求【3】PUT请求【4】DELETE 请求【5】汇总工具类,通过传参实现4种请求 【二】HttpClient 实现四种请求方式的示例【1】GET请求【2】POST 请求【3】PUT 请求【…...
人工智能之深度学习的革命性突破
深度学习的革命性突破 深度学习是机器学习的一个子领域,通过模拟人脑神经网络的结构和功能,实现对复杂数据的高效处理。近年来,深度学习在计算机视觉、自然语言处理、语音识别等领域取得了革命性突破。本文将深入探讨深度学习的核心架构、突…...