Python 实现带进度条的异步多文件下载
·
📌 摘要
本文详细介绍了如何使用 Python + asyncio + aiohttp + tqdm 实现一个 带进度条的异步多文件下载器。相比传统的同步下载方式,异步下载不仅能够显著提高下载速度,还能在终端显示每个文件的实时下载进度条,适用于大文件、多文件并发下载等场景。文章提供了详细中文注释的完整代码示例,读者可以直接拷贝运行。同时也介绍了核心原理、依赖库、适用场景等内容,非常适合学习 Python 异步 IO 编程的开发者参考。
🧰 使用的库说明
-
asyncio:Python 内置的异步协程库,用于并发执行任务。
-
aiohttp:支持用于异步 HTTP 请求,比 requests 更适合同步下载。
-
tqdm:终端显示进度条的工具。
安装依赖:
pip install aiohttp tqdm
🚀 异步下载的优势
-
无需多线程,也能同时下载多个文件
-
避免同步阻塞,大幅提升下载速度
-
每个任务都能显示独立进度条
📦 核心思路
-
使用
aiohttp.ClientSession()进行异步请求 -
使用
await response.content.read(1024)异步读取内容 -
使用
tqdm显示进度条 -
使用
asyncio.gather()并发执行多个下载任务
🎯 适用场景
-
下载多个大文件(Zip、MP4、模型文件等)
-
写爬虫批量下载文件
-
后台批处理任务
-
分布式下载系统
import aiohttp
import asyncio
from tqdm import tqdm
# 异步下载函数
async def download_file(url, destination):
"""
异步下载文件并显示下载进度条
:param url: 文件下载地址
:param destination: 本地保存文件路径
"""
# 创建 aiohttp 会话
async with aiohttp.ClientSession() as session:
# 发送 GET 请求
async with session.get(url) as response:
# 获取文件总大小(如果服务器支持)
total_size = int(response.headers.get("Content-Length", 0))
# 打开本地文件,准备写入下载内容
with open(destination, "wb") as f:
# tqdm 进度条
progress_bar = tqdm(
total=total_size, # 总大小
unit="B", # 单位:字节
unit_scale=True, # 自动转换 KB / MB
desc=f"下载中: {destination}" # 显示的标题
)
# 持续读取数据(每次读取 1024 字节)
while True:
chunk = await response.content.read(1024)
if not chunk: # 读取完毕
break
f.write(chunk)
progress_bar.update(len(chunk)) # 更新进度条
progress_bar.close() # 下载完成后关闭进度条
# 主异步函数
async def main():
"""
批量创建多个下载任务,并异步并发执行
"""
# 要下载的文件列表(可自行扩展)
download_tasks = [
{
"url": "http://example.com/file1.zip",
"destination": "file1.zip"
},
{
"url": "http://example.com/file2.zip",
"destination": "file2.zip"
},
# 可以继续添加更多文件
]
# 为每个任务创建一个 download_file 协程
tasks = [
download_file(task["url"], task["destination"])
for task in download_tasks
]
# 并发执行所有下载任务
await asyncio.gather(*tasks)
# 程序入口
if __name__ == "__main__":
# 运行异步主函数
asyncio.run(main())
更多推荐
所有评论(0)