Python异步编程完全教程:asyncio/aiohttp核心用法与实战

news/2025/12/9 19:27:47/文章来源:https://www.cnblogs.com/xyash/p/19328129

异步编程是Python提升I/O密集型任务效率的核心技术,尤其适用于网络请求、文件读写、数据库交互等场景。

一、异步编程核心概念:同步vs异步

1. 同步编程(传统方式)

同步代码按顺序执行,一个任务未完成时,后续任务必须等待(“阻塞”)。例如:

import timedef sync_task(name, delay):print(f"任务{name}开始执行")time.sleep(delay)  # 模拟I/O阻塞(如网络请求)print(f"任务{name}执行完成")# 同步执行3个任务
start = time.time()
sync_task("A", 2)
sync_task("B", 1)
sync_task("C", 3)
print(f"总耗时:{time.time()-start:.2f}秒")

运行结果

任务A开始执行
任务A执行完成
任务B开始执行
任务B执行完成
任务C开始执行
任务C执行完成
总耗时:6.00秒

同步执行的总耗时是所有任务耗时之和,效率极低。

2. 异步编程(非阻塞方式)

异步编程中,当某个任务遇到I/O阻塞时,程序不会等待,而是切换到其他任务执行,待阻塞任务完成后再回来继续处理。核心特点:

  • 非阻塞:I/O等待期间不占用CPU;
  • 单线程:异步任务在单线程内切换执行(区别于多线程);
  • 事件循环:核心调度器,负责管理异步任务的执行、切换。

二、asyncio核心基础:协程与事件循环

asyncio是Python内置的异步编程库,核心是协程(Coroutine)事件循环(Event Loop)

1. 协程定义与基本语法

协程是异步任务的载体,通过async def定义,await触发阻塞并切换任务:

import asyncio
import time# 定义协程函数(必须用async def)
async def async_task(name, delay):print(f"任务{name}开始执行")await asyncio.sleep(delay)  # 异步睡眠(模拟I/O阻塞,不能用time.sleep)print(f"任务{name}执行完成")# 主协程(程序入口)
async def main():# 创建任务列表tasks = [async_task("A", 2),async_task("B", 1),async_task("C", 3)]# 并发执行所有任务await asyncio.gather(*tasks)# 启动事件循环(Python 3.7+简化写法)
start = time.time()
asyncio.run(main())
print(f"总耗时:{time.time()-start:.2f}秒")

运行结果

任务A开始执行
任务B开始执行
任务C开始执行
任务B执行完成
任务A执行完成
任务C执行完成
总耗时:3.00秒

异步执行总耗时等于最长任务的耗时(3秒),效率提升一倍。

2. 核心语法解析

语法/函数 作用
async def 函数名() 定义协程函数,调用后返回协程对象(不会立即执行)
await 可等待对象 暂停当前协程,切换到事件循环执行其他任务,直到“可等待对象”完成后返回
asyncio.run() 创建事件循环→运行主协程→关闭事件循环(Python 3.7+)
asyncio.gather() 并发执行多个协程,等待所有协程完成后返回结果列表
asyncio.sleep() 异步睡眠(模拟I/O阻塞),必须用await调用(区别于time.sleep)

3. 任务(Task):主动调度协程

asyncio.create_task()可将协程包装为“任务”,主动加入事件循环调度:

import asyncioasync def async_task(name, delay):print(f"任务{name}开始执行")await asyncio.sleep(delay)return f"任务{name}完成(耗时{delay}秒)"async def main():# 创建任务(立即加入事件循环)task1 = asyncio.create_task(async_task("A", 2))task2 = asyncio.create_task(async_task("B", 1))# 等待任务完成并获取返回值result1 = await task1result2 = await task2print(result1)print(result2)asyncio.run(main())

运行结果

任务A开始执行
任务B开始执行
任务B完成(耗时1秒)
任务A完成(耗时2秒)

三、aiohttp:异步HTTP请求(实战核心)

asyncio仅处理基础异步逻辑,aiohttp是Python最常用的异步HTTP客户端/服务端库,专门解决同步requests库的性能瓶颈。

1. 环境准备

# 安装aiohttp
pip install aiohttp

2. 基础异步请求:单URL请求

import asyncio
import aiohttpasync def fetch_url(session, url):"""异步请求单个URL"""try:async with session.get(url, timeout=aiohttp.ClientTimeout(total=10)) as response:# 获取响应状态码和内容status = response.statuscontent = await response.text()  # 文本内容(response.json()获取JSON)return {"url": url,"status": status,"content_length": len(content)}except Exception as e:return {"url": url,"error": str(e)}async def main():# 创建异步HTTP会话(复用连接,提升效率)async with aiohttp.ClientSession() as session:result = await fetch_url(session, "https://www.baidu.com")print(f"请求结果:{result}")asyncio.run(main())

运行结果

请求结果:{'url': 'https://www.baidu.com', 'status': 200, 'content_length': 2443}

3. 批量异步请求:多URL并发

import asyncio
import aiohttp
import timeasync def fetch_url(session, url):"""异步请求单个URL"""try:async with session.get(url, timeout=aiohttp.ClientTimeout(total=10)) as response:await response.text()return f"{url} → 状态码:{response.status}"except Exception as e:return f"{url} → 错误:{str(e)}"async def main():# 待请求的URL列表urls = ["https://www.baidu.com","https://www.taobao.com","https://www.jd.com","https://www.163.com","https://www.github.com"]# 创建会话并批量请求async with aiohttp.ClientSession() as session:# 创建任务列表tasks = [fetch_url(session, url) for url in urls]# 并发执行所有任务results = await asyncio.gather(*tasks)# 打印结果for res in results:print(res)# 计时对比同步请求
start = time.time()
asyncio.run(main())
print(f"总耗时:{time.time()-start:.2f}秒")

运行结果

https://www.baidu.com → 状态码:200
https://www.taobao.com → 状态码:200
https://www.jd.com → 状态码:200
https://www.163.com → 状态码:200
https://www.github.com → 状态码:200
总耗时:0.85秒

(同步requests请求相同URL约需3-5秒,异步效率提升4-6倍)

4. 进阶:限制并发数(避免被封IP)

批量请求时直接并发所有任务可能触发目标服务器反爬,需限制并发数:

import asyncio
import aiohttp
import time# 限制最大并发数为3
MAX_CONCURRENT = 3async def fetch_url(session, url, semaphore):"""带并发限制的异步请求"""# 信号量控制并发数async with semaphore:try:async with session.get(url, timeout=10) as response:await response.text()return f"{url} → 成功"except Exception as e:return f"{url} → 失败:{str(e)}"async def main():urls = [f"https://httpbin.org/get?num={i}" for i in range(10)]  # 10个测试URLsemaphore = asyncio.Semaphore(MAX_CONCURRENT)  # 信号量async with aiohttp.ClientSession() as session:tasks = [fetch_url(session, url, semaphore) for url in urls]results = await asyncio.gather(*tasks)for res in results:print(res)start = time.time()
asyncio.run(main())
print(f"总耗时:{time.time()-start:.2f}秒")

核心原理asyncio.Semaphore(3)限制同时执行的任务数为3,避免一次性发起大量请求。

四、异步编程常见问题与避坑指南

1. 避免在异步代码中使用同步阻塞函数

time.sleep()requests.get()pymysql.connect()等同步阻塞函数会卡住整个事件循环,必须替换为异步版本:

同步操作 异步替代方案
time.sleep(delay) await asyncio.sleep(delay)
requests.get(url) aiohttp.ClientSession().get(url)
pymysql(MySQL) aiomysql
redis(Redis) aioredis

2. 协程函数调用必须加await

直接调用协程函数不会执行,仅返回协程对象:

async def test():print("协程执行")# 错误:仅返回协程对象,不执行
test()
# 正确:await触发执行
await test()

3. 异常处理:捕获异步任务的错误

import asyncioasync def error_task():raise ValueError("异步任务出错了")async def main():try:await error_task()except ValueError as e:print(f"捕获到错误:{e}")asyncio.run(main())

4. 异步代码无法在同步函数中直接运行

如需在同步函数中调用异步代码,需通过asyncio.run()或事件循环:

import asyncioasync def async_func():return "异步函数返回值"# 同步函数中调用异步代码
def sync_func():result = asyncio.run(async_func())print(result)sync_func()

五、实战案例:异步爬虫(爬取网页标题)

以下案例实现“批量爬取URL标题 → 保存到CSV文件”的完整异步流程:

import asyncio
import aiohttp
import csv
from bs4 import BeautifulSoup  # 需安装:pip install beautifulsoup4# 限制并发数
MAX_CONCURRENT = 5async def fetch_title(session, url, semaphore):"""异步爬取网页标题"""async with semaphore:try:async with session.get(url, timeout=10) as response:if response.status != 200:return {"url": url, "title": "请求失败", "status": response.status}html = await response.text()soup = BeautifulSoup(html, "html.parser")title = soup.title.string.strip() if soup.title else "无标题"return {"url": url, "title": title, "status": response.status}except Exception as e:return {"url": url, "title": f"错误:{str(e)}", "status": "异常"}async def main():# 待爬取的URL列表urls = ["xxxxx",]# 初始化信号量和会话semaphore = asyncio.Semaphore(MAX_CONCURRENT)async with aiohttp.ClientSession() as session:# 创建任务并执行tasks = [fetch_title(session, url, semaphore) for url in urls]results = await asyncio.gather(*tasks)# 保存到CSV文件with open("url_titles.csv", "w", newline="", encoding="utf-8") as f:writer = csv.DictWriter(f, fieldnames=["url", "title", "status"])writer.writeheader()writer.writerows(results)print("爬取完成!结果已保存到url_titles.csv")# 启动程序
if __name__ == "__main__":asyncio.run(main())

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

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

相关文章

2025年12月北京园林景观公司标杆推荐:北京缘晟源,园林景观绿化养护、庭院绿化、覆盖京津冀多场景绿化服务

随着 “双碳” 目标深入推进、城市更新与乡村振兴战略落地,园林绿化行业正迎来生态化、精细化、多元化转型,2025 年国内市场规模预计达 1.2 万亿元。立体绿化、节水园林、资源循环等新型需求持续增长,但市场扩容也导…

2025年比较好的除湿机品牌高评价厂家推荐榜

2025年比较好的除湿机品牌高评价厂家推荐榜行业背景与市场趋势随着全球气候变化加剧和人们对室内空气质量要求的提高,除湿机市场在2025年迎来了新一轮的增长。据行业数据显示,中国除湿机市场规模已突破百亿元,年复合…

2025年热门的步入式恒温恒湿试验箱/高低温试验箱最新TOP厂家排名

2025年热门的步入式恒温恒湿试验箱/高低温试验箱TOP厂家排名随着工业4.0和智能制造技术的快速发展,环境试验设备作为产品质量控制的关键环节,正迎来前所未有的市场需求。步入式恒温恒湿试验箱和高低温试验箱作为模拟…

Python 知识讲解 + 示例代码 + 讲解

按照章节 + 知识点给出 Python 知识讲解 + 示例代码 + 讲解。第四章:字符串的格式化方法 Python 中常用的三种字符串格式化方式:1. 百分号格式化(%) 语法 "%格式说明符" % (值)示例 name = "Tom&qu…

python考点讲解- TYUT

给出“是什么→为什么→怎么用→易错点→小练习”的完整讲解,每个知识点都配上可直接运行的 Python 代码与中文注释。第四章 字符串的格式化方法% 老式格式化(了解即可,维护老代码会遇到) str.format() 新式格式化…

完整教程:Vue-Loader 深度解析:原理、使用与最佳实践

完整教程:Vue-Loader 深度解析:原理、使用与最佳实践2025-12-09 19:12 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; d…

2025年口碑好的平开不锈钢合页/钢质门不锈钢合页TOP实力厂家推荐榜

2025年口碑好的平开不锈钢合页/钢质门不锈钢合页TOP实力厂家推荐榜 行业背景与市场趋势 随着建筑行业对高品质五金配件的需求不断提升,不锈钢合页作为门控五金的核心部件,其性能、耐用性和美观度直接影响门的使用寿…

Ganache-CLI以太坊私网JSON-RPC接口大全:从入门到精通 - 指南

Ganache-CLI以太坊私网JSON-RPC接口大全:从入门到精通 - 指南pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Con…

02 音视频开发--Windows环境搭建FFmpeg+Qt+Visual studio 2022

FFmpeg下载安装 FFmpeg下载官网打开命令窗口输入ffmpeg -versionQT下载安装 1.在Windows系统下,先创建QT账户 [QT]https://www.qt.io/qt下载地址(Linux) https://www.qt.io/download-qt-installer-ossCSDN教程 http…

#题解#洛谷P1045 麦森数#快速幂#高精度乘法#

P1045 [NOIP 2003 普及组] 麦森数 - 洛谷 分析2p-1的位数,易知:跟2p的位数相同,为[log10(2)*p]+1求末尾500位数字:高精度乘法+快速幂代码 #include<bits/stdc++.h> #define int long long #define endl \n …

MySQL主从之间具有不同数据类型的列的复制

MySQL主从之间具有不同数据类型的列的复制2025-12-09 19:08 abce 阅读(0) 评论(0) 收藏 举报主库和从库同一表中对应列的数据类型理想情况下应相同。但只要满足特定条件,此要求并非始终要求被严格执行。通常可将特…

2025实用AI洗头机品牌推荐榜:仪美天引领智能洗护,各大品牌各展所长

在如今的生活节奏越来越快的情况下,AI洗头机因为其高效、智能的洗护体验而逐渐成为了美容美发、养生保健等新刚需。为了帮助大家准确地挑选出适合自己的AI洗头机品牌,本次推荐榜将从企业的资质、技术水平、市场表现等…

2025年口碑好的大型面粉机行业内知名厂家排行榜

2025年口碑好的大型面粉机行业内知名厂家排行榜行业背景与市场趋势随着全球粮食加工行业的持续发展,大型面粉机械作为粮食加工产业链中的核心设备,其市场需求呈现出稳定增长态势。2025年,受人口增长、食品工业升级和…

2025年口碑好的高压SVG动态无功补偿装置/高压无功补偿装置厂家实力及用户口碑排行榜

2025年口碑好的高压SVG动态无功补偿装置/高压无功补偿装置厂家实力及用户口碑排行榜行业背景与市场趋势随着我国电力系统的快速发展,电网规模不断扩大,电力负荷日益复杂化,对电能质量的要求也越来越高。高压SVG动态…

2025年口碑好的全屋定制衣柜灯厂家最新实力排行

2025年口碑好的全屋定制衣柜灯厂家实力排行行业背景与市场趋势随着人们对家居品质要求的不断提升,全屋定制衣柜灯市场迎来了快速发展期。2025年,智能照明、健康光环境与个性化定制成为行业三大关键词。据市场调研数据…

一类通过寻找区间关键点从而弱化子区间的限制而优化复杂度的问题

那些我不会的感觉很深刻啊!感觉那么不可做的问题,分个类突然就十分容易了啊! CF1801G 给定一个字符串 \(t\) 和 \(n\) 个字符串 \(s_1, s_2, s_3, \dots, s_n\) \(m\) 次询问 \(t[l_i, r_i]\) 中出现了多少次 \(s_1…

计算机硬件基础知识 - Invinc

本文介绍一些计算机硬件方面的基础知识,旨在为电脑组装、配置升级、检测维修等提供一些帮助。本文介绍一些计算机硬件方面的基础知识,旨在为电脑组装、配置升级、检测维修等提供一些帮助。内存 内存检测工具 MemTest…

2025年评价高的耐高温钛杯/大冰花钛杯行业内口碑厂家排行榜

2025年评价高的耐高温钛杯/大冰花钛杯行业内口碑厂家排行榜行业背景与市场趋势随着消费者健康意识的不断提升和户外生活方式的流行,钛制水杯市场近年来呈现爆发式增长。钛金属因其轻质、耐腐蚀、无金属异味、耐高温等…

2025年专业定制触摸一体机最新TOP厂家排名

2025年专业定制触摸一体机TOP厂家排名行业背景与市场趋势随着数字化转型浪潮席卷全球,触摸一体机作为人机交互的重要载体,在各行各业的应用场景不断拓展。2025年,全球触摸屏市场规模预计将达到150亿美元,年复合增长…

自建机场

docker run --rm ghcr.io/xtls/xray-core:latest uuid记录 uuid wget https://github.com/XTLS/Xray-core/releases/download/v1.8.4/Xray-linux-64.zip apt-get install -y unzip unzip Xray-linux-64.zip ./xray x25…