如何动态调整Python爬虫的Request请求延迟

引言

在网络爬虫开发中,合理控制请求延迟(Request Delay)是避免被封禁、提高爬取效率的关键。固定延迟(如 **<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">time.sleep(1)</font>**)虽然简单,但在面对不同网站的反爬策略时可能不够灵活。动态调整请求延迟能够更智能地适应目标网站的变化,提高爬虫的稳定性和效率。

本文将介绍如何动态调整Python爬虫的请求延迟,包括:

  1. 固定延迟 vs. 动态延迟的优劣
  2. 基于响应状态码的动态延迟调整
  3. 基于请求频率的动态延迟调整
  4. 结合代理IP和用户代理(User-Agent)优化延迟

1. 固定延迟 vs. 动态延迟

1.1 固定延迟

固定延迟是最简单的控制方式,例如:

import time
import requestsfor url in urls:response = requests.get(url)time.sleep(1)  # 固定延迟1秒

优点:实现简单,适用于低频率爬取。
缺点

  • 如果目标网站允许更快的请求,固定延迟会降低爬取效率。
  • 如果目标网站检测到固定间隔请求,可能触发反爬机制。

1.2 动态延迟

动态延迟根据网站响应、请求频率等因素调整等待时间,例如:

  • 如果服务器返回 **<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">429 Too Many Requests</font>**,则增加延迟。
  • 如果连续多次请求成功,则适当降低延迟。
  • 随机化延迟,模拟人类操作。

2. 基于响应状态码的动态延迟

如果服务器返回 **<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">429</font>****<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">503</font>**,说明请求频率过高,此时应增加延迟;如果正常返回 **<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">200</font>**,则可以适当降低延迟。

实现代码

import time
import requests
import randomclass DynamicDelayCrawler:def __init__(self, base_delay=1, max_delay=5):self.base_delay = base_delay  # 基础延迟self.max_delay = max_delay    # 最大延迟self.current_delay = base_delaydef adjust_delay(self, status_code):if status_code == 429:  # 请求过多,增加延迟self.current_delay = min(self.current_delay * 2, self.max_delay)elif status_code == 200:  # 请求成功,尝试降低延迟self.current_delay = max(self.current_delay * 0.9, self.base_delay)def crawl(self, url):try:response = requests.get(url)self.adjust_delay(response.status_code)print(f"URL: {url}, Status: {response.status_code}, Delay: {self.current_delay:.2f}s")time.sleep(self.current_delay)return response.textexcept Exception as e:print(f"Error fetching {url}: {e}")time.sleep(self.current_delay * 2)  # 出错时增加延迟return None# 测试
crawler = DynamicDelayCrawler(base_delay=1, max_delay=10)
urls = ["https://example.com/page1", "https://example.com/page2", "https://example.com/page3"]
for url in urls:crawler.crawl(url)

3. 基于请求频率的动态延迟

某些网站可能没有明确的 **<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">429</font>** 响应,但会通过其他方式限制爬虫(如封IP)。我们可以统计单位时间内的请求次数,动态调整延迟。

实现代码

import time
import requests
from collections import dequeclass RequestRateLimiter:def __init__(self, max_requests=10, time_window=10):self.max_requests = max_requests  # 时间窗口内允许的最大请求数self.time_window = time_window    # 时间窗口(秒)self.request_times = deque()      # 存储请求时间戳def wait_if_needed(self):now = time.time()# 移除超出时间窗口的请求记录while self.request_times and now - self.request_times[0] > self.time_window:self.request_times.popleft()if len(self.request_times) >= self.max_requests:# 计算需要等待的时间wait_time = self.time_window - (now - self.request_times[0])print(f"Rate limit reached, waiting {wait_time:.2f}s")time.sleep(wait_time)self.request_times.append(now)# 测试
limiter = RequestRateLimiter(max_requests=5, time_window=5)  # 5秒内最多5次请求
urls = [f"https://example.com/page{i}" for i in range(10)]
for url in urls:limiter.wait_if_needed()response = requests.get(url)print(f"Fetched {url}, Status: {response.status_code}")

4. 结合代理IP和随机User-Agent优化

动态调整延迟的同时,使用代理IP和随机User-Agent可以进一步降低被封禁的风险。

实现代码

import random
import time
import requests
from fake_useragent import UserAgentclass AdvancedCrawler:def __init__(self, base_delay=1, max_delay=10):self.base_delay = base_delayself.max_delay = max_delayself.current_delay = base_delayself.ua = UserAgent()# 添加指定的代理信息self.proxyHost = "www.16yun.cn"self.proxyPort = "5445"self.proxyUser = "16QMSOML"self.proxyPass = "280651"self.proxies = [f"http://{self.proxyUser}:{self.proxyPass}@{self.proxyHost}:{self.proxyPort}",# 如果需要保留原有代理,可以将它们也加入到列表中# "<url id="d02v8neruqkqvdqddo90" type="url" status="failed" title="" wc="0">http://proxy1.example.com:8080</url> ",# "<url id="d02v8neruqkqvdqddo9g" type="url" status="failed" title="" wc="0">http://proxy2.example.com:8080</url> ",]def get_random_proxy(self):return random.choice(self.proxies) if self.proxies else Nonedef adjust_delay(self, status_code):if status_code == 429:self.current_delay = min(self.current_delay * 2, self.max_delay)elif status_code == 200:self.current_delay = max(self.current_delay * 0.9, self.base_delay)def crawl(self, url):headers = {"User-Agent": self.ua.random}proxy = self.get_random_proxy()try:response = requests.get(url,headers=headers,proxies={"http": proxy, "https": proxy} if proxy else None,timeout=10)self.adjust_delay(response.status_code)print(f"URL: {url}, Status: {response.status_code}, Delay: {self.current_delay:.2f}s")time.sleep(self.current_delay + random.uniform(0, 0.5))  # 增加随机抖动return response.textexcept Exception as e:print(f"Error fetching {url}: {e}")time.sleep(self.current_delay * 2)return None# 测试
crawler = AdvancedCrawler(base_delay=1, max_delay=10)
urls = [f"https://example.com/page{i}" for i in range(5)]
for url in urls:crawler.crawl(url)

5总结

动态调整Python爬虫的Request请求延迟是一种有效的优化策略,可以提高爬虫的稳定性和效率。通过基于响应时间、服务器负载和反爬机制的动态调整策略,爬虫可以在复杂的网络环境中灵活运行,同时降低被封禁的风险。本文提供的代码示例展示了如何实现动态调整请求延迟,开发者可以根据实际需求进行进一步优化和扩展。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/76669.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

QSS【QT】

文章目录 QSSid选择器 & 类型选择器伪类选择器盒子模型 QSS 设置样式的时候&#xff0c;是可以指定某个控件来设置的。 指定控件之后&#xff0c;此时的样式就会针对这个指定的控件&#xff0c;也会针对子控件生效 ui->pushButton_2->setStyleSheet("QPushButt…

学习笔记二十二—— 并发五大常见陷阱

⚠️ 并发五大常见陷阱 目录 数据竞争 (Data Race)死锁 (Deadlock)竞态条件 & 饿死现象 (Race Condition & Starvation)悬挂指针 (Dangling Pointer)重复释放 (Double Free)开发自查清单 1. 数据竞争 (Data Race) 专业定义 两个及以上线程在缺乏同步的情况下同时访问同…

ESP32- 开发笔记- 硬件设计-ESP32-C3基本电路

ESP32的最小电路 1 ESP32固件下载 ESP32 有多种下载(烧录)固件的方式,具体选择取决于开发环境和硬件连接。以下是常见的几种下载方式: 1.1 USB 串口下载(最常用) 适用场景:通过 USB 转串口芯片(如 CP2102、CH340)连接电脑,使用 esptool 或其他工具烧录固件。这里…

Qt6文档阅读笔记-RESTful API Server解析

本例使用QHttpServer创建RESTful API服务端。 此例接收REST风格的请求&#xff0c;与此例与之对应的客户端是RESTful Color Palette API client。 满足REST限制的API被称为RESTful风格的API。 RESTful API服务端一般包括&#xff1a;create、read、update、delete操作。 其中…

HarmonyOS 基础语法概述 UI范式

ArkUI框架 - UI范式 ArkTS的基本组成 装饰器&#xff1a; 用于装饰类、结构、方法以及变量&#xff0c;并赋予其特殊的含义。如上述示例中Entry、Component和State都是装饰器&#xff0c;Component表示自定义组件&#xff0c;Entry表示该自定义组件为入口组件&#xff0c;Stat…

Docker镜像基本概念与构建指南

Docker镜像基本概念与构建指南 一、Docker镜像基本概念 Docker镜像是容器运行的基础&#xff0c;包含应用程序及其运行所需的文件系统、依赖库、环境变量和配置。其核心特性包括&#xff1a; 只读性&#xff1a;镜像本身不可修改&#xff0c;容器运行时在镜像层之上创建可写…

如何避免 CDN 缓存泄漏用户隐私数据

CDN 通过将内容缓存到全球各地的边缘服务器上,显著缩短了数据传输的物理距离,从而加速了内容的交付。然而,这一技术在提升性能的同时,也悄然埋下了一颗隐私隐患的种子——缓存数据可能被不当访问或泄漏,进而暴露用户的敏感信息。 目录 禁用对用户个人信息的缓存 仅缓存…

软考中级数据库系统工程师学习资料分享

软考中级数据库系统工程师考试对于很多 IT 从业者和计算机专业的大学生来说&#xff0c;是一个重要的职业资格认证。它不仅能够提升个人的专业技能&#xff0c;还能为职业发展增添有力的砝码。今天&#xff0c;我将为大家分享一套全面且实用的学习资料&#xff0c;帮助大家更好…

数据处理: 均值漂移聚类(Mean Shift)

一、 基本原理 Mean Shift是一种基于密度的非参数聚类算法&#xff0c;不需要预先指定簇的数量&#xff0c;而是通过寻找数据空间中密度最大的区域来自动确定聚类中心, 适合图像分割和目标跟踪等。 算法步骤 初始化&#xff1a;对每个数据点作为起点。 迭代&#xff1a;计算…

辛格迪客户案例 | 苏州富士莱医药GMP培训管理(TMS)项目

一、案例概述 富士莱医药股份有限公司位于美丽的江南水乡常熟&#xff0c;前身为常熟富士莱医药化工有限公司&#xff0c;从建厂初期面积仅有10余亩&#xff0c;逐步扩展到100余亩。近年来公司飞速发展&#xff0c;以黑马姿态发展成为中国专业生产硫辛酸系列产品、肌肽系列产品…

SQL注入相关知识

一、布尔盲注 1、布尔盲简介 布尔盲注是一种SQL注入攻击技术&#xff0c;用于在无法直接获取数据库查询结果的情况下&#xff0c;通过页面的响应来判断注入语句的真假&#xff0c;从而获取数据库中的敏感信息 2、布尔盲注工作原理 布尔盲注的核心在于利用SQL语句的布尔逻辑…

Linux基础学习--linux的文件权限与目录配置

linux的文件权限与目录配置 1.用户与用户组 在Linux中&#xff0c;每个文件都有相当多的属性和权限&#xff0c;其中最重要的概念就是文件的拥有者。 1.1 文件拥有者 Linux是一个多人多任务的系统&#xff0c;常常有多人共用一台主机的情况出现&#xff0c;因此在系统中可以…

【数据可视化-19】智能手机用户行为可视化分析

🧑 博主简介:曾任某智慧城市类企业算法总监,目前在美国市场的物流公司从事高级算法工程师一职,深耕人工智能领域,精通python数据挖掘、可视化、机器学习等,发表过AI相关的专利并多次在AI类比赛中获奖。CSDN人工智能领域的优质创作者,提供AI相关的技术咨询、项目开发和个…

vue项目通过GetCapabilities获取wmts服务元数据信息并在openlayers进行叠加显示

vue项目通过openlayers加载wmts服务示例&#xff1a; <template><div id"map" ref"mapContainer"></div> </template><script> import ol/ol.css; import Map from ol/Map; import View from ol/View; import TileLayer fr…

JavaWeb学习打卡-Day1-分层解耦、Spring IOC、DI

三层架构 Controller&#xff08;控制层&#xff09;&#xff1a;接收前端发送的请求&#xff0c;对请求进行处理&#xff0c;并响应数据。Service&#xff08;业务逻辑层&#xff09;&#xff1a;处理具体的业务逻辑。DAO&#xff08;数据访问层/持久层&#xff09;&#xff…

【含文档+PPT+源码】基于Python爬虫二手房价格预测与可视化系统的设计与实现

项目介绍 本课程演示的是一款基于Python爬虫二手房价格预测与可视化系统&#xff0c;主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的 Java 学习者。 包含&#xff1a;项目源码、项目文档、数据库脚本、软件工具等所有资料 带你从零开始部署运行本套系统 该项…

游戏引擎学习第229天

仓库:https://gitee.com/mrxiao_com/2d_game_5 回顾上次内容并介绍今天的主题 上次留下的是一个非常简单的任务&#xff0c;至少第一步是非常简单的。我们需要在渲染器中加入排序功能&#xff0c;这样我们的精灵&#xff08;sprites&#xff09;才能以正确的顺序显示。为此我…

【“星瑞” O6 评测】—NPU 部署 face parser 模型

前言 瑞莎星睿 O6 (Radxa Orion O6) 拥有高达 28.8TOPs NPU (Neural Processing Unit) 算力&#xff0c;支持 INT4 / INT8 / INT16 / FP16 / BF16 和 TF32 类型的加速。这里通过通过官方的工具链进行FaceParsingBiSeNet的部署 1. FaceParsingBiSeNet onnx 推理 首先从百度网盘…

单例模式的使用场景 以及 饿汉式写法(智能指针)

单例模式的使用场景 以及 饿汉式写法&#xff08;智能指针&#xff09; 饿汉式&#xff1a;创建类时就已经创建好了类的实例&#xff08;用智能指针实现&#xff09;什么时候用单例模式&#xff1a;1. 全局配置管理2. 日志系统3. 资源管理器4. 硬件设备访问总结 饿汉式&#xf…

微信小程序的全局变量(quanjubianliang)

在微信小程序开发中&#xff0c;管理和使用全局变量是一种常见的需求。例如&#xff0c;可以通过小程序的App实例和globalData对象来实现全局变量的存储和共享。以下是详细说明&#xff1a; 1. 全局变量的定义 微信小程序提供了 App() 函数&#xff0c;其中可以定义一个 global…