爬虫工作量由小到大的思维转变---<第四十章 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代码解析:
可以细分为几个重要部分,每个部分都有特定的目的。我们将对这些部分进行详细解析:
-
初始化和属性赋值 __init__方法中实现了RedisProxyMiddleware的初始化方法。它接收来自Scrapy的参数,如Redis数据库的连接信息、代理关键字、批量大小、最大失败次数和锁定键。这些参数在实例化时保存为类的属性,以供后续使用。此外,还初始化了一个空集合用于缓存代理IP。
-
from_crawler方法 from_crawler方法是一个类方法,用于从Crawler对象获取参数,并实例化RedisProxyMiddleware类。通过获取Scrapy设置中的Redis连接信息和其他参数,我们可以方便地初始化中间件并与Redis建立连接。
-
process_request方法 process_request方法是RedisProxyMiddleware中的关键方法,用于处理Spider请求以获取代理IP。在该方法中,首先检查请求中是否存在代理IP(存储在请求的meta数据中),以及该代理IP是否在锁定键指定的Redis集合中。如果请求中没有代理IP或代理IP被锁定,将调用fetch_proxies方法来获取新的代理IP。
-
fetch_proxies方法 fetch_proxies方法用于从Redis数据库获取一组全新的代理。通过使用srandmember方法,它从Redis中的代理关键字指定的集合中获取指定数量的随机代理IP。如果成功获取到代理IP,则将其添加到cached_proxies集合中。然后,根据获取的代理IP数量,记录调试日志或警告信息,以供进一步的调试和分析。
总结:
RedisProxyMiddleware在Scrapy框架中实现了一个IP代理池的管理中间件。通过对代码进行解析,我们了解了它的初始化方法、参数设置、处理请求方法和获取全新代理IP的逻辑。RedisProxyMiddleware的设计目标是提供一个简单、可扩展和稳定的IP代理池解决方案,以满足分布式爬虫的需求。通过精确管理代理IP,并根据需要进行动态调整和切换,我们可以提高爬虫的稳定性和数据抓取效率。
相关文章:
爬虫工作量由小到大的思维转变---<第四十章 Scrapy Redis 实现IP代理池管理的最佳实践>
前言: 本篇是要结合上篇一起看的姊妹篇:爬虫工作量由小到大的思维转变---<第三十九章 Scrapy-redis 常用的那个RetryMiddleware>-CSDN博客 IP代理池的管理对于确保爬虫的稳定性和数据抓取的匿名性至关重要。围绕Scrapy-Redis框架和一个具体的IP代理池中…...
C# 实现 XOR 密码
XOR密码(异或密码)是一种简单的加密算法,它使用异或(XOR)操作来对明文和密钥进行加密和解密。 异或操作是一种位运算,它对两个二进制数的对应位进行比较,如果两个位相同(都为0或都为…...
【Web前端开发基础】CSS3之空间转换和动画
CSS3之空间转换和动画 目录 CSS3之空间转换和动画一、空间转换1.1 概述1.2 3D转换常用的属性1.3 3D转换:translate3d(位移)1.4 3D转换:perspective(视角)1.5 3D转换:rotate3d(旋转&a…...
Go实现一个简单的烟花秀效果(附带源码)
在 Go 语言中,要实现烟花秀效果可以使用 github.com/fogleman/gg 包进行绘图。以下是一个简单的例子: 首先,确保你已经安装了(有时候需要梯子才可以安装) github.com/fogleman/gg 包: go get -u github.c…...
【数学建模】插值与拟合
文章目录 插值插值方法用Python解决插值问题 拟合最小二乘拟合数据拟合的Python实现 适用情况 处理由试验、测量得到的大量数据或一些过于复杂而不便于计算的函数表达式时,构造一个简单函数作为要考察数据或复杂函数的近似 定义 给定一组数据,需要确定满…...
全卷积网络:革新图像分析
一、介绍 全卷积网络(FCN)的出现标志着计算机视觉领域的一个重要里程碑,特别是在涉及图像分析的任务中。本文深入探讨了 FCN 的概念、它们的架构、它们与传统卷积神经网络 (CNN) 的区别以及它们在各个领域的应用。 就像…...
ubuntu20.04 格式化 硬盘 扩展硬盘GParted
如何在 Ubuntu 22.04 LTS 上安装分区编辑器 GParted?_gparted安装-CSDN博客 sudo apt install gparted 步骤5:启动GParted 安装完成后,您可以在应用程序菜单中找到GParted。点击它以启动分区编辑器。 通过以上步骤,您可以在Ubun…...
docker的资源限制(cgroup)
前瞻 Docker 通过 Cgroup 来控制容器使用的资源配额,包括 CPU、内存、磁盘三大方面, 基本覆盖了常见的资源配额和使用量控制。 Cgroup 是 ControlGroups 的缩写,是 Linux 内核提供的一种可以限制、记录、隔离进程组所使用的物理资源(如 CPU、…...
ChatGPT与文心一言:应用示例与体验比较
ChatGPT 和文心一言哪个更好用? 为了更好地感受ChatGPT和文心一言这两款AI助手如何在实际运用中竞相辉映,我将提供一些典型的应用示例。这些示例都取自真实的用户体验,以帮助解释这两种工具如何让日常生活或工作变得更加轻松。 ChatGPT Ch…...
紫光展锐T760_芯片性能介绍_展锐T760安卓核心板定制
展锐T760核心板是一款基于国产5G芯片的智能模块,采用紫光展锐T760制程工艺为台积电6nm工艺,支持工艺具有出色的能效表现。其采用主流的44架构的八核设计,包括4颗2.2GHz A76核心和4颗A55核心设计,内存单元板载可达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 问题一:增加超时机制,防止长期持有…...
MATLAB中实现机械臂逆运动学求解的方法之一是使用阻尼最小二乘法
MATLAB中实现机械臂逆运动学求解的方法之一是使用阻尼最小二乘法。阻尼最小二乘法通常用于处理数值求解问题中的不稳定性和噪声。以下是一个简单的MATLAB代码示例,演示了机械臂逆运动学的阻尼最小二乘法求解: % 机械臂参数 L1 1; % 机械臂长度 L2 1;…...
2024.1.24 GNSS 学习笔记
1.伪距观测值公式 2.载波相位观测值公式 3.单点定位技术(Single Point Positionin, SPP) 仅使用伪距观测值,不使用其他的辅助信息获得ECEF框架下绝对定位技术。 使用广播星历的轨钟进行定位,考虑到轨钟的米级精度,所以对于<1米的误差&…...
2024-01-22(MongoDB)
1.Mongodb使用的业务场景: 传统的关系型数据库/mysql在“三高”需求以及应对web2.0的网站需求面前,有点力不从心,什么是“三高”需求: a. 对数据库高并发的读写需求 b. 对海量数据的高效率存储和访问需求 c. 对数据库的高可扩…...
无人机航迹规划(六):七种元启发算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划(提供MATLAB代码)
一、七种算法(DBO、LO、SWO、COA、LSO、KOA、GRO)简介 1、蜣螂优化算法DBO 蜣螂优化算法(Dung beetle optimizer,DBO)由Jiankai Xue和Bo Shen于2022年提出,该算法主要受蜣螂的滚球、跳舞、觅食、偷窃和繁…...
《WebKit 技术内幕》学习之十二(2):安全机制
2 沙箱模型 2.1 原理 一般而言,对于网络上的网页中的JavaScript代码和插件是不受信的(除非是经过认证的网站),特别是一些故意设计侵入浏览器运行的主机代码更是非常危险,通过一些手段或者浏览器中的漏洞,…...
算法优化:LeetCode第122场双周赛解题策略与技巧
接下来会以刷常规题为主 ,周赛的难题想要独立做出来还是有一定难度的,需要消耗大量时间 比赛地址 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服务 提示:以下是本篇文章正文内容,下面案例可供参…...
Linux 文件类型,目录与路径,文件与目录管理
文件类型 后面的字符表示文件类型标志 普通文件:-(纯文本文件,二进制文件,数据格式文件) 如文本文件、图片、程序文件等。 目录文件:d(directory) 用来存放其他文件或子目录。 设备…...
可靠性+灵活性:电力载波技术在楼宇自控中的核心价值
可靠性灵活性:电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中,电力载波技术(PLC)凭借其独特的优势,正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据,无需额外布…...
抖音增长新引擎:品融电商,一站式全案代运营领跑者
抖音增长新引擎:品融电商,一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中,品牌如何破浪前行?自建团队成本高、效果难控;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...
什么是库存周转?如何用进销存系统提高库存周转率?
你可能听说过这样一句话: “利润不是赚出来的,是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业,很多企业看着销售不错,账上却没钱、利润也不见了,一翻库存才发现: 一堆卖不动的旧货…...
2021-03-15 iview一些问题
1.iview 在使用tree组件时,发现没有set类的方法,只有get,那么要改变tree值,只能遍历treeData,递归修改treeData的checked,发现无法更改,原因在于check模式下,子元素的勾选状态跟父节…...
服务器--宝塔命令
一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行! sudo su - 1. CentOS 系统: yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...
2025季度云服务器排行榜
在全球云服务器市场,各厂商的排名和地位并非一成不变,而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势,对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析: 一、全球“三巨头”…...
云原生安全实战:API网关Kong的鉴权与限流详解
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关(API Gateway) API网关是微服务架构中的核心组件,负责统一管理所有API的流量入口。它像一座…...
DingDing机器人群消息推送
文章目录 1 新建机器人2 API文档说明3 代码编写 1 新建机器人 点击群设置 下滑到群管理的机器人,点击进入 添加机器人 选择自定义Webhook服务 点击添加 设置安全设置,详见说明文档 成功后,记录Webhook 2 API文档说明 点击设置说明 查看自…...
【前端异常】JavaScript错误处理:分析 Uncaught (in promise) error
在前端开发中,JavaScript 异常是不可避免的。随着现代前端应用越来越多地使用异步操作(如 Promise、async/await 等),开发者常常会遇到 Uncaught (in promise) error 错误。这个错误是由于未正确处理 Promise 的拒绝(r…...
