You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用httpx AsyncClient搭配tqdm.asyncio下载进度条显示异常如何解决

问题根源

tqdm默认按迭代次数计数,每遍历到一个元素就自动+1,无法感知你迭代的chunk实际字节长度。因此不管你是否指定aiter_bytes的chunk_size,tqdm都认为每次仅下载了1字节,最终和你设置的总字节数total单位不匹配,出现进度、速度、剩余时间完全失真的问题。

正确实现方案

你需要手动控制进度条的更新量,每次遍历到chunk后,将实际接收的字节长度传给tqdm的update方法即可,参考代码如下:

import tqdm.asyncio

async with self.http.stream(method='GET', url=download_url) as res:
    # 可选:校验请求响应正常,避免下载到错误内容
    res.raise_for_status()
    # 如果未提前获取文件总大小,可从响应头读取(需要服务端返回Content-Length)
    total_size = int(res.headers.get("Content-Length", 0))
    
    # 初始化异步tqdm,不直接绑定迭代器
    async with tqdm.asyncio.tqdm(
        desc=name,
        unit="iB",
        unit_scale=True,
        unit_divisor=1024,
        total=total_size # 用你之前的size变量也可以,确保单位是字节即可
    ) as pbar:
        # 用上下文管理器处理文件,避免忘记关闭
        with open(file_path, "wb") as f:
            # chunk_size可根据需求调整,示例为1M
            async for chunk in res.aiter_bytes(chunk_size=1024 * 1024):
                write_len = f.write(chunk)
                # 手动更新进度,步进为实际写入的字节数
                pbar.update(write_len)
关键说明
  • chunk_size可自由调整,不会影响进度统计的准确性,因为每次更新的是实际字节长度,和chunk大小无关
  • 你之前配置的unit/unit_scale/unit_divisor参数无需修改,只要进度更新的单位和total的单位统一为字节,显示就会完全正常
  • 如果服务端不返回Content-Length头,total可以传0,此时tqdm会显示已下载的字节数和实时速度,但不会展示总进度条和剩余时间

内容的提问来源于stack exchange,提问作者unknown_horse

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 07:15:02