Python使用aiohttp实现每秒千次的网页抓取
前言先把标题里的前提点破「每秒千次」对单一站点发起请求不是技术指标而是压站行为。任何有一定规模的网站一秒收到上千次来自同一来源的请求都会被判定为异常流量并触发限流甚至封禁从合规角度这也不符合「礼貌抓取」的基本共识。所以本文不教你冲这个数字而是反过来讲怎么用asyncioaiohttp把并发压到一个可控、可解释的值并配合限速访问公开页面。需要明确aiohttp是第三方库不属于 Python 标准库需要单独安装。本文只描述它的典型用法思路具体 API、参数名与行为以 aiohttp 官方文档为准。正文真正要讲的是两件事一是aiohttp怎么和事件循环配合做异步请求二是用asyncio.Semaphore控制并发上限——这才是高并发抓取里最有价值的工程技能比任何「每秒多少次」的口号都管用。一、aiohttp 是什么为什么用它标准库urllib.request是同步的一个请求要阻塞到响应回来。放进协程里它会把整个事件循环卡住。aiohttp提供了基于asyncio的 HTTP 客户端让「发出请求」和「等待响应」这两步都能await等待期间事件循环可以去处理其他请求。一个最典型的用法骨架是先建一个客户端会话session在会话里发起请求请求返回的对象作为异步上下文管理器读取响应体。# 适用于 Python 3.8需要第三方库 aiohttpAPI 细节以其官方文档为准import asyncioimport aiohttpasync def fetch_one(session, url):async with session.get(url) as resp:resp.raise_for_status()return await resp.text()async def main():async with aiohttp.ClientSession() as session:html await fetch_one(session, https://example.com/)print(len(html))asyncio.run(main())这里有两个实践原则一个会话复用连接。ClientSession内部维护连接池复用 TCP 连接能显著减少握手开销。不要每请求都新建 session。会话要用async with或手动await session.close()。忘了关闭会留下「Unclosed client session」警告长期运行会泄漏资源。二、用 Semaphore 限制并发上限无限并发是这个领域最大的坑。你以为「有多少 URL 就并发多少」是高效实际上本地文件描述符会被耗尽对目标站构成突发压力容易被封大量连接同时等待反而拖慢整体。正确做法是用信号量asyncio.Semaphore把「同时进行」的请求数量锁死在一个小值上。信号量的语义是拿不到名额就等有人释放了才轮到下一个。# 适用于 Python 3.8需要第三方库 aiohttpimport asyncioimport aiohttpasync def fetch_one(session, sem, url):async with sem: # 超过上限就在这里排队async with session.get(url) as resp:resp.raise_for_status()return await resp.text()async def crawl(urls, limit5, delay0.5):sem asyncio.Semaphore(limit) # 最多 limit 个请求同时进行results []async with aiohttp.ClientSession() as session:async def task(u):html await fetch_one(session, sem, u)await asyncio.sleep(delay) # 每个请求后主动退让降低频率return htmltasks [asyncio.create_task(task(u)) for u in urls]for coro in asyncio.as_completed(tasks):results.append(await coro)return results信号量里有几个值得注意的细节limit设多大没有万能值。对公开页面从个位数起步观察目标站的响应时间与是否返回 429/503再决定要不要调整。宁可慢不要打到对方。用asyncio.sleep(delay)做请求间隔是简单的限速手段想更精确可以算令牌桶但对个人规模的采集没必要上那么复杂。Semaphore是asyncio自带的协作式原语不能用threading.Semaphore代替后者会阻塞事件循环。三、合规抓取的最低要求并发能力是一把双刃剑用之前先满足这几条遵守 robots.txt标准库urllib.robotparser可以解析它。被标注为不允许的路径就别抓。只抓公开页面不要试图绕过登录墙、付费墙——本文也不提供任何此类做法。限速与退避既控制并发数也在收到 429/503 时退避重试而不是加倍猛冲。标明身份给请求带上说明用途的 User-Agent方便站长识别与联系别伪装成浏览器做对抗。尊重数据许可抓下来的内容能否存储、二次使用要看网站条款与当地法规。# 适用于 Python 3.8import urllib.robotparserdef can_fetch(url: str, user_agent: str *) - bool:rp urllib.robotparser.RobotFileParser()rp.set_url(https://example.com/robots.txt)# 实际使用时需先 rp.read()会发起网络请求这里只演示判定逻辑rp.parse([User-agent: *, Disallow: /private/])return rp.can_fetch(user_agent, url)上面为了可读性直接用parse()喂了几行规则文本真实使用时可以先rp.read()去拉取 robots.txt。can_fetch(useragent, url)返回布尔值告诉你这个地址是否允许抓取。四、一个更完整的骨架带超时与错误隔离把前面的点拼起来就是一段可以直接改改就用的骨架会话复用、并发上限、单请求超时、失败不拖垮整体。# 适用于 Python 3.8需要第三方库 aiohttpAPI 细节以其官方文档为准import asyncioimport aiohttpasync def fetch(session, sem, url, timeout10.0):async with sem:try:async with session.get(url, timeoutaiohttp.ClientTimeout(totaltimeout)) as resp:resp.raise_for_status()return url, await resp.text()except (aiohttp.ClientError, asyncio.TimeoutError) as exc:return url, fERROR: {type(exc).__name__}async def main(urls):sem asyncio.Semaphore(5)async with aiohttp.ClientSession() as session:tasks [asyncio.create_task(fetch(session, sem, u)) for u in urls]for done in asyncio.as_completed(tasks):url, body await doneprint(url, len(body))if __name__ __main__:asyncio.run(main([https://example.com/] * 10))要点解释每个任务内部包了try/except单个请求失败只影响它自己其他任务照跑。这是「错误隔离」。超时用aiohttp.ClientTimeout其具体参数名以官方文档为准配合asyncio.wait_for也可以但一层就够不要叠。as_completed让结果按完成先后返回不必等最慢的那个。再次强调把Semaphore(5)改成Semaphore(1000)不会让你「每秒抓一千次」只会让你更快被封、更快把本地文件描述符用光。常见坑点把「每秒千次」当目标❌ 无限并发猛冲单一站点✅ 用Semaphore把并发压到个位数并加请求间隔每个请求都新建 ClientSession❌ 在fetch里aiohttp.ClientSession()✅ 全程复用一个 session用async with管理生命周期session 用完不关❌ 脚本结束冒出 Unclosed client session 警告✅async with aiohttp.ClientSession() as session:或显式await session.close()用线程版同步原语❌threading.Semaphore/queue.Queue放进协程✅ 用asyncio.Semaphore/asyncio.Queue不读响应、不判断状态码❌ 只session.get(url)就算成功✅resp.raise_for_status()并对 429/503 做退避收到限流还加倍重试❌ 429 后立刻再发更多请求✅ 指数退避仍被拒就停手绕过 robots.txt 或登录墙❌ 想方设法抓不允许访问的内容✅ 只用合规途径访问公开页面遵守站点规则把 aiohttp 的 API 当标准库背书❌ 凭记忆写参数名并声称是官方接口✅ 不确定就以 aiohttp 官方文档为准只写确定的用法总结主题错误认知正确做法并发数越多越快用Semaphore限制上限会话每请求一个 session全程复用用后关闭频率冲到极限加延迟、退避、遵 robots.txt异常一失败全崩任务内 try/except 隔离库属性标准库第三方以官方文档为准aiohttp的价值在于让成百上千个「等待响应」的时刻重叠起来而不是让你把某个站点打垮。真正需要练的功夫是知道并发上限该设多少、什么时候退避、哪些内容不该抓。把这些想清楚你写的采集脚本才是能长期跑下去的。

相关新闻

Gradle手动创建Web工程并打War包部署Tomcat实战指南

Gradle手动创建Web工程并打War包部署Tomcat实战指南

这一篇是Gradle入门系列里的第四篇,前几篇把Gradle的环境、基本命令和构建脚本语法聊完之后,很多人卡在了同一个地方:我到底怎么用它建一个能丢进Tomcat跑的web工程。网上一搜教程,要么是Spring Boot的starter模板,要么…

2026/10/17 13:06:45 阅读更多 →
阿里云短信接口开发实战:验证码发送与高频报错排查

阿里云短信接口开发实战:验证码发送与高频报错排查

简介:阿里云短信接口开发是企业在用户验证、通知推送等场景下的常见需求,这份资源面向.NET后端开发者,提供了一套完整的短信服务对接示例,涵盖账号注册、AccessKey申请、接口参数构造、HTTP请求发送及异常重试机制等关键环节&…

2026/10/17 13:10:02 阅读更多 →
若当标准型变换矩阵P怎么求?广义特征向量链与算例详解

若当标准型变换矩阵P怎么求?广义特征向量链与算例详解

说句实话,线性代数里“会算特征值”和“会求若当标准型的变换矩阵”完全是两码事。很多人在考卷上能写对若当块,比如 [ J\begin{pmatrix}2&1&0\0&2&1\0&0&2\end{pmatrix}, ] 但真到要写一个可逆矩阵 (P),使得 (P^{-1…

2026/10/16 7:08:03 阅读更多 →

最新新闻

车载激光雷达原理与车规级工程实践全解析

车载激光雷达原理与车规级工程实践全解析

简介:本资源是一份面向自动驾驶工程师、传感器研发人员及高校车辆/光电专业研究者的车载激光雷达技术深度综述,系统梳理从基础原理到产业落地的关键脉络。内容覆盖激光雷达发展历程(含DARPA挑战赛里程碑事件)、按探测方式&#xf…

2026/10/17 18:46:08 阅读更多 →
CentOS 7离线安装JDK 7u25:解压部署与环境变量配置实战

CentOS 7离线安装JDK 7u25:解压部署与环境变量配置实战

还在给 CentOS 7 装 JDK 7u25 的人,多半不是图新鲜,而是被老项目拴住了;再有就是部署脚本里写死了 jdk-7u25-linux-x64.tar.gz 这个文件名。我自己这两年帮人搭过好几套这样的环境,原因都差不多:某个老中间件版本锁定、…

2026/10/17 18:46:08 阅读更多 →
基于YOLOv11的脑瘤MRI目标检测实践与调优指南

基于YOLOv11的脑瘤MRI目标检测实践与调优指南

1. 选题思路:脑瘤影像检测为什么用 YOLOv11 做主体如果让我复盘这个毕设最值得说的部分,我会把“选题定在哪一类任务”排在第一。当时我也犹豫过:脑瘤检测听起来更适合做图像分割,或者干脆做成一个分类模型,把 MRI 影像…

2026/10/17 18:46:08 阅读更多 →
IDA逆向入门实战:从C程序到类型识别与数组操作全流程

IDA逆向入门实战:从C程序到类型识别与数组操作全流程

简介:这份《IDA简易教程共十四章(图)》面向逆向工程初学者与安全分析入门者,以图文并茂的方式讲解IDA Pro的基础操作,帮助读者解决二进制反汇编入门难、数据类型识别混乱等问题。教程从C语言小程序示例切入&#xff0c…

2026/10/17 18:46:08 阅读更多 →
RESTful接口中Hibernate使用指南:实体、DTO与懒加载实战

RESTful接口中Hibernate使用指南:实体、DTO与懒加载实战

做后端开发这些年,我最大的感受之一是: Hibernate 单独用没什么,一放进 RESTful 服务 里,各种"灵异事件"就冒出来了。明明是简单的查询接口,越写越慢;明明实体类里啥都配好了,前端…

2026/10/17 18:46:08 阅读更多 →
金融微服务架构下如何保证资金安全与数据一致性

金融微服务架构下如何保证资金安全与数据一致性

1. 从“financial-services”这个标题里,我读出了什么“financial-services”这个标题,乍一看像是一个再普通不过的行业标签,甚至有点像某个开源仓库或者内部项目的代号。但恰恰是这种看似宽泛的命名,反而藏着不少值得深挖的东西。…

2026/10/17 18:45:07 阅读更多 →

日新闻

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

简介:《DeepSeek使用方法.pdf》是一份面向DeepSeek入门及进阶用户的完整使用指南,重点围绕V3与R1两款模型的能力差异与适用场景展开,帮助读者根据任务类型与成本选择合适的模型。资源共1个PDF文件,压缩包大小约311KB,篇…

2026/10/17 0:00:25 阅读更多 →
200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

简介:这是一份聚焦DeepSeek提示词优化的《200Deepseek润色指令》PDF文档,共收录两百余条可直接套用的润色指令,涵盖语法修正、风格统一、逻辑梳理、表达精炼等维度,并针对商务写作、学术论文、广告文案等场景给出差异化建议。文档…

2026/10/17 0:00:25 阅读更多 →
OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

简介:本资源是一份基于OpenCV的本科课程设计完整报告,面向计算机视觉初学者、图像处理学习者及高校通信/信息类专业学生,解决物体智能计数与检测结果结构化记录的实际问题。项目覆盖图像预处理、轮廓检测、边界框绘制、轨迹栏交互式参数调节、…

2026/10/17 0:00:25 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/16 21:35:51 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/17 1:44:59 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/16 15:04:24 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 21:54:38 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 14:23:36 阅读更多 →