Python 协程 + asyncio 模拟 HTTP 请求
·
一、为什么用协程 + asyncio 模拟 HTTP 请求?
- 高并发:协程+asyncio可以在单线程内高效地并发发起成百上千个HTTP请求,极大提升IO密集型任务的效率。
- 非阻塞:不会像多线程那样有线程切换和锁的开销,也不会像同步代码那样阻塞等待响应。
- 易于编写和维护:用同步风格(async/await)写异步代码,逻辑清晰。
二、常用库
- Python标准库的
asyncio只提供了事件循环和基础IO,不直接支持HTTP协议。 - 推荐用aiohttp库,它是基于asyncio的异步HTTP客户端/服务器库。
三、完整示例代码
1. 安装aiohttp
pip install aiohttp
2. 代码实现
import asyncio
import aiohttp
async def fetch(session, url):
print(f'Start fetching: {url}')
async with session.get(url) as response:
html = await response.text()
print(f'Finished fetching: {url}, length: {len(html)}')
return html
async def main():
urls = [
'https://www.example.com',
'https://www.python.org',
'https://www.baidu.com',
# 可以添加更多URL
]
async with aiohttp.ClientSession() as session:
tasks = [fetch(session, url) for url in urls]
results = await asyncio.gather(*tasks)
print('All requests done!')
if __name__ == '__main__':
asyncio.run(main())
四、逐行详细解释
1. 导入模块
import asyncio
import aiohttp
asyncio:Python标准库,提供事件循环和协程支持。aiohttp:第三方库,提供异步HTTP客户端。
2. 定义异步请求函数
async def fetch(session, url):
print(f'Start fetching: {url}')
async with session.get(url) as response:
html = await response.text()
print(f'Finished fetching: {url}, length: {len(html)}')
return html
async def fetch(session, url):定义一个协程函数,参数为aiohttp的会话对象和目标URL。async with session.get(url) as response:异步发起HTTP GET请求,获取响应对象。html = await response.text():异步读取响应内容(字符串)。- 打印请求开始和结束信息,返回网页内容。
3. 定义主协程
async def main():
urls = [
'https://www.example.com',
'https://www.python.org',
'https://www.baidu.com',
]
async with aiohttp.ClientSession() as session:
tasks = [fetch(session, url) for url in urls]
results = await asyncio.gather(*tasks)
print('All requests done!')
urls:待请求的URL列表。async with aiohttp.ClientSession() as session:创建一个异步HTTP会话,自动管理连接池和资源。tasks = [fetch(session, url) for url in urls]:为每个URL创建一个fetch协程任务。results = await asyncio.gather(*tasks):并发调度所有任务,等待全部完成,返回结果列表。- 打印所有请求完成。
4. 启动事件循环
if __name__ == '__main__':
asyncio.run(main())
- 启动事件循环,调度并执行主协程
main(),直到其执行完毕。
五、执行流程
- 程序启动,进入事件循环,执行
main()。 - 创建HTTP会话,生成所有fetch任务。
- 并发发起所有HTTP请求,每个请求遇到IO等待时自动让出控制权。
- 所有请求完成后,输出结果。
六、输出示例
Start fetching: https://www.example.com
Start fetching: https://www.python.org
Start fetching: https://www.baidu.com
Finished fetching: https://www.example.com, length: 1256
Finished fetching: https://www.python.org, length: 48876
Finished fetching: https://www.baidu.com, length: 2381
All requests done!
(实际输出顺序可能因网络延迟不同而不同)
七、核心原理总结
- 协程+asyncio让你用同步风格写高并发异步HTTP请求。
- aiohttp提供了异步HTTP客户端,支持连接池、会话复用等高效特性。
- 适合爬虫、批量数据采集、接口压力测试等IO密集型场景。
更多推荐



所有评论(0)