当前位置: 首页 > news >正文

爬虫工作量由小到大的思维转变---<第四十章 Scrapy Redis 实现IP代理池管理的最佳实践>

前言:

本篇是要结合上篇一起看的姊妹篇:爬虫工作量由小到大的思维转变---<第三十九章 Scrapy-redis 常用的那个RetryMiddleware>-CSDN博客

IP代理池的管理对于确保爬虫的稳定性和数据抓取的匿名性至关重要。围绕Scrapy-Redis框架和一个具体的IP代理池中间件代码,在分布式爬虫中如何使用Redis实现IP代理池的管理,这篇文章进行探讨一下  (当然,还有更好的方案,希望大家反驳我)

正文:

IP代理池与Scrapy-Redis的结合

源代码

import random
import time
import redisclass RedisProxyMiddleware(object):def __init__(self, redis_host, redis_port, redis_db, proxy_key, batch_size, max_failures, lock_key):# 初始化Redis连接self.redis = redis.StrictRedis(host=redis_host, port=redis_port, db=redis_db)# Redis 代理池keyself.proxy_key = proxy_key# 每次从Redis获取代理的数量self.batch_size = batch_size# 代理IP允许的最大失败次数self.max_failures = max_failures# 代理IP锁的keyself.lock_key = lock_key# 本地缓存代理IP的集合self.cached_proxies = set()@classmethoddef from_crawler(cls, crawler):settings = crawler.settings# 创建中间件实例并返回return cls(redis_host=settings.get('REDIS_HOST'),redis_port=settings.get('REDIS_PORT'),redis_db=settings.get('REDIS_DB'),proxy_key=settings.get('REDIS_PROXY_KEY'),batch_size=settings.get('BATCH_SIZE'),max_failures=settings.get('MAX_FAILURES'),lock_key=settings.get('REDIS_PROXY_LOCK_KEY'))def process_request(self, request, spider):# 如果请求中没有代理IP,或者请求中的代理IP已经被加入到了代理锁if 'proxy' not in request.meta or self.redis.sismember(self.lock_key, request.meta['proxy']):# 如果缓存的代理IP数量小于批量大小,则尝试获取新的代理IPif len(self.cached_proxies) < self.batch_size:self.fetch_proxies(spider)# 如果本地缓存中有代理IP,从中随机选择一个if self.cached_proxies:request.meta['proxy'] = random.choice(list(self.cached_proxies))def fetch_proxies(self, spider):# 尝试获取代理锁,如果获取锁成功,则进行代理IP的刷新if self.acquire_lock(spider):try:spider.logger.debug('代理锁已获取,准备提取新的代理IP。')fetched_proxies = self.redis.srandmember(self.proxy_key, self.batch_size)if fetched_proxies:# 清空本地代理IP缓存,并添加新获取的代理IPself.cached_proxies.clear()self.cached_proxies.update(fetched_proxies)spider.logger.debug('已提取{}个新的代理IP。'.format(len(fetched_proxies)))else:spider.logger.warning('无法获取到新的代理IP,继续使用现有的代理IP。')finally:# 无论提取代理IP成功与否,都释放代理锁self.release_lock(spider)spider.logger.debug('代理锁已释放。')else:# 如果没有获取到代理锁,则等待,等待时间应根据实际情况调整spider.logger.debug('代理锁正被其他实例占用,等待重试。')time.sleep(5)def acquire_lock(self, spider):# 尝试加锁,用于控制代理IP的获取status = self.redis.set(self.lock_key, 1, nx=True, ex=60)  # 锁的有效期设为60秒if status:spider.logger.debug('代理锁已加锁。')else:spider.logger.debug('代理锁加锁失败,锁已存在。')return statusdef release_lock(self, spider):# 释放锁,其他实例可以继绀获取新代理self.redis.delete(self.lock_key)spider.logger.debug('代理锁已释放。')
RedisProxyMiddleware代码解析:

可以细分为几个重要部分,每个部分都有特定的目的。我们将对这些部分进行详细解析:

  1. 初始化和属性赋值 __init__方法中实现了RedisProxyMiddleware的初始化方法。它接收来自Scrapy的参数,如Redis数据库的连接信息、代理关键字、批量大小、最大失败次数和锁定键。这些参数在实例化时保存为类的属性,以供后续使用。此外,还初始化了一个空集合用于缓存代理IP。

  2. from_crawler方法 from_crawler方法是一个类方法,用于从Crawler对象获取参数,并实例化RedisProxyMiddleware类。通过获取Scrapy设置中的Redis连接信息和其他参数,我们可以方便地初始化中间件并与Redis建立连接。

  3. process_request方法 process_request方法是RedisProxyMiddleware中的关键方法,用于处理Spider请求以获取代理IP。在该方法中,首先检查请求中是否存在代理IP(存储在请求的meta数据中),以及该代理IP是否在锁定键指定的Redis集合中。如果请求中没有代理IP或代理IP被锁定,将调用fetch_proxies方法来获取新的代理IP。

  4. fetch_proxies方法 fetch_proxies方法用于从Redis数据库获取一组全新的代理。通过使用srandmember方法,它从Redis中的代理关键字指定的集合中获取指定数量的随机代理IP。如果成功获取到代理IP,则将其添加到cached_proxies集合中。然后,根据获取的代理IP数量,记录调试日志或警告信息,以供进一步的调试和分析。

总结:

RedisProxyMiddleware在Scrapy框架中实现了一个IP代理池的管理中间件。通过对代码进行解析,我们了解了它的初始化方法、参数设置、处理请求方法和获取全新代理IP的逻辑。RedisProxyMiddleware的设计目标是提供一个简单、可扩展和稳定的IP代理池解决方案,以满足分布式爬虫的需求。通过精确管理代理IP,并根据需要进行动态调整和切换,我们可以提高爬虫的稳定性和数据抓取效率。

相关文章:

爬虫工作量由小到大的思维转变---<第四十章 Scrapy Redis 实现IP代理池管理的最佳实践>

前言: 本篇是要结合上篇一起看的姊妹篇:爬虫工作量由小到大的思维转变---&#xff1c;第三十九章 Scrapy-redis 常用的那个RetryMiddleware&#xff1e;-CSDN博客 IP代理池的管理对于确保爬虫的稳定性和数据抓取的匿名性至关重要。围绕Scrapy-Redis框架和一个具体的IP代理池中…...

C# 实现 XOR 密码

XOR密码&#xff08;异或密码&#xff09;是一种简单的加密算法&#xff0c;它使用异或&#xff08;XOR&#xff09;操作来对明文和密钥进行加密和解密。 异或操作是一种位运算&#xff0c;它对两个二进制数的对应位进行比较&#xff0c;如果两个位相同&#xff08;都为0或都为…...

【Web前端开发基础】CSS3之空间转换和动画

CSS3之空间转换和动画 目录 CSS3之空间转换和动画一、空间转换1.1 概述1.2 3D转换常用的属性1.3 3D转换&#xff1a;translate3d&#xff08;位移&#xff09;1.4 3D转换&#xff1a;perspective&#xff08;视角&#xff09;1.5 3D转换&#xff1a;rotate3d&#xff08;旋转&a…...

Go实现一个简单的烟花秀效果(附带源码)

在 Go 语言中&#xff0c;要实现烟花秀效果可以使用 github.com/fogleman/gg 包进行绘图。以下是一个简单的例子&#xff1a; 首先&#xff0c;确保你已经安装了&#xff08;有时候需要梯子才可以安装&#xff09; github.com/fogleman/gg 包&#xff1a; go get -u github.c…...

【数学建模】插值与拟合

文章目录 插值插值方法用Python解决插值问题 拟合最小二乘拟合数据拟合的Python实现 适用情况 处理由试验、测量得到的大量数据或一些过于复杂而不便于计算的函数表达式时&#xff0c;构造一个简单函数作为要考察数据或复杂函数的近似 定义 给定一组数据&#xff0c;需要确定满…...

全卷积网络:革新图像分析

一、介绍 全卷积网络&#xff08;FCN&#xff09;的出现标志着计算机视觉领域的一个重要里程碑&#xff0c;特别是在涉及图像分析的任务中。本文深入探讨了 FCN 的概念、它们的架构、它们与传统卷积神经网络 &#xff08;CNN&#xff09; 的区别以及它们在各个领域的应用。 就像…...

ubuntu20.04 格式化 硬盘 扩展硬盘GParted

如何在 Ubuntu 22.04 LTS 上安装分区编辑器 GParted&#xff1f;_gparted安装-CSDN博客 sudo apt install gparted 步骤5&#xff1a;启动GParted 安装完成后&#xff0c;您可以在应用程序菜单中找到GParted。点击它以启动分区编辑器。 通过以上步骤&#xff0c;您可以在Ubun…...

docker的资源限制(cgroup)

前瞻 Docker 通过 Cgroup 来控制容器使用的资源配额&#xff0c;包括 CPU、内存、磁盘三大方面&#xff0c; 基本覆盖了常见的资源配额和使用量控制。 Cgroup 是 ControlGroups 的缩写&#xff0c;是 Linux 内核提供的一种可以限制、记录、隔离进程组所使用的物理资源(如 CPU、…...

ChatGPT与文心一言:应用示例与体验比较

ChatGPT 和文心一言哪个更好用&#xff1f; 为了更好地感受ChatGPT和文心一言这两款AI助手如何在实际运用中竞相辉映&#xff0c;我将提供一些典型的应用示例。这些示例都取自真实的用户体验&#xff0c;以帮助解释这两种工具如何让日常生活或工作变得更加轻松。 ChatGPT Ch…...

紫光展锐T760_芯片性能介绍_展锐T760安卓核心板定制

展锐T760核心板是一款基于国产5G芯片的智能模块&#xff0c;采用紫光展锐T760制程工艺为台积电6nm工艺&#xff0c;支持工艺具有出色的能效表现。其采用主流的44架构的八核设计&#xff0c;包括4颗2.2GHz A76核心和4颗A55核心设计&#xff0c;内存单元板载可达8GB Ram256GB ROM…...

从动力系统研究看当今数学界

6.3... Milnor’s definition of “attractors” which has been criticized above by us). The work of [KSS2] of asserting the existence of “nice open set” of Ω(p.148) would be likely not verified, for example we think the first sentence “… since f is nont…...

【征服redis15】分布式锁的功能与整体设计方案

目录 1. 分布式锁的概念 2.基于数据库做分布式锁 2.1 基于表主键唯一做分布式锁 2.2 基于表字段版本号做分布式锁 2.3 基于数据库排他锁做分布式锁 3.使用Redis做分布式锁 3.1 redis实现分布式锁的基本原理 3.2 问题一&#xff1a;增加超时机制&#xff0c;防止长期持有…...

MATLAB中实现机械臂逆运动学求解的方法之一是使用阻尼最小二乘法

MATLAB中实现机械臂逆运动学求解的方法之一是使用阻尼最小二乘法。阻尼最小二乘法通常用于处理数值求解问题中的不稳定性和噪声。以下是一个简单的MATLAB代码示例&#xff0c;演示了机械臂逆运动学的阻尼最小二乘法求解&#xff1a; % 机械臂参数 L1 1; % 机械臂长度 L2 1;…...

2024.1.24 GNSS 学习笔记

1.伪距观测值公式 2.载波相位观测值公式 3.单点定位技术(Single Point Positionin, SPP) 仅使用伪距观测值&#xff0c;不使用其他的辅助信息获得ECEF框架下绝对定位技术。 使用广播星历的轨钟进行定位&#xff0c;考虑到轨钟的米级精度&#xff0c;所以对于<1米的误差&…...

2024-01-22(MongoDB)

1.Mongodb使用的业务场景&#xff1a; 传统的关系型数据库/mysql在“三高”需求以及应对web2.0的网站需求面前&#xff0c;有点力不从心&#xff0c;什么是“三高”需求&#xff1a; a. 对数据库高并发的读写需求 b. 对海量数据的高效率存储和访问需求 c. 对数据库的高可扩…...

无人机航迹规划(六):七种元启发算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划(提供MATLAB代码)

一、七种算法&#xff08;DBO、LO、SWO、COA、LSO、KOA、GRO&#xff09;简介 1、蜣螂优化算法DBO 蜣螂优化算法&#xff08;Dung beetle optimizer&#xff0c;DBO&#xff09;由Jiankai Xue和Bo Shen于2022年提出&#xff0c;该算法主要受蜣螂的滚球、跳舞、觅食、偷窃和繁…...

《WebKit 技术内幕》学习之十二(2):安全机制

2 沙箱模型 2.1 原理 一般而言&#xff0c;对于网络上的网页中的JavaScript代码和插件是不受信的&#xff08;除非是经过认证的网站&#xff09;&#xff0c;特别是一些故意设计侵入浏览器运行的主机代码更是非常危险&#xff0c;通过一些手段或者浏览器中的漏洞&#xff0c…...

算法优化:LeetCode第122场双周赛解题策略与技巧

接下来会以刷常规题为主 &#xff0c;周赛的难题想要独立做出来还是有一定难度的&#xff0c;需要消耗大量时间 比赛地址 3011. 判断一个数组是否可以变为有序 public class Solution {public int minimumCost(int[] nums) {if (nums.length < 3) {// 数组长度小于3时&a…...

IDEA导出jar

1、选择导出方式 2、选择Main Class 3、构建jar...

Win10/11中VMware Workstation设置网络桥接模式

文章目录 一、添加VMware Bridge Protocol服务二、配置桥接参数1.启用系统Device Install Service服务2.配置VMware 需要确认物理网卡是否有添加VMware Bridge Protocol服务 添加VMware Bridge Protocol服务 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参…...

23-Oracle 23 ai 区块链表(Blockchain Table)

小伙伴有没有在金融强合规的领域中遇见&#xff0c;必须要保持数据不可变&#xff0c;管理员都无法修改和留痕的要求。比如医疗的电子病历中&#xff0c;影像检查检验结果不可篡改行的&#xff0c;药品追溯过程中数据只可插入无法删除的特性需求&#xff1b;登录日志、修改日志…...

【大模型RAG】Docker 一键部署 Milvus 完整攻略

本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装&#xff1b;只需暴露 19530&#xff08;gRPC&#xff09;与 9091&#xff08;HTTP/WebUI&#xff09;两个端口&#xff0c;即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...

深入理解JavaScript设计模式之单例模式

目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式&#xff08;Singleton Pattern&#…...

定时器任务——若依源码分析

分析util包下面的工具类schedule utils&#xff1a; ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类&#xff0c;封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz&#xff0c;先构建任务的 JobD…...

MODBUS TCP转CANopen 技术赋能高效协同作业

在现代工业自动化领域&#xff0c;MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步&#xff0c;这两种通讯协议也正在被逐步融合&#xff0c;形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...

C# 类和继承(抽象类)

抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...

令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍

文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结&#xff1a; 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析&#xff1a; 实际业务去理解体会统一注…...

精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南

精益数据分析&#xff08;97/126&#xff09;&#xff1a;邮件营销与用户参与度的关键指标优化指南 在数字化营销时代&#xff0c;邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天&#xff0c;我们将深入解析邮件打开率、网站可用性、页面参与时…...

R 语言科研绘图第 55 期 --- 网络图-聚类

在发表科研论文的过程中&#xff0c;科研绘图是必不可少的&#xff0c;一张好看的图形会是文章很大的加分项。 为了便于使用&#xff0c;本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中&#xff0c;获取方式&#xff1a; R 语言科研绘图模板 --- sciRplothttps://mp.…...

android13 app的触摸问题定位分析流程

一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...