You need to enable JavaScript to run this app. Python下载大文件时tqdm进度条为何延迟至下载完成才显示,如何让其启动即展示
优惠活动
大模型
产品
解决方案
定价
更多

Python下载大文件时tqdm进度条为何延迟至下载完成才显示,如何让其启动即展示

进度条延迟到下载完成才显示的问题修复

问题根因

你的实现存在两处逻辑错误,共同导致了进度条显示滞后:

  • 错误的总文件大小取值逻辑
    代码中写的total = float(content_length)存在明显问题:这个content_length既没有从当前带stream=True的下载响应中提取,也没有做空值兼容。实际运行时,这个变量要么是提前请求过程中遗留的旧值,要么是因为在走到下载循环前已经把响应流全部读取完毕,导致后续resp.iter_content直接进入空迭代,循环第一次就执行完所有流程,tqdm刚初始化就直接跳到100%,观感上就是文件下完了进度条才弹出来。
    正确的取值应该直接从下载请求的响应头中读取总大小,兼容无返回头的异常场景:
    resp = requests.get(url, stream=True)
    # 从响应头获取文件总大小,获取失败时设置为0避免报错
    total = float(resp.headers.get('Content-Length', 0))
    
  • 终端输出缓冲阻塞
    Python默认对终端输出启用块缓冲,tqdm的进度条是高频短间隔输出的内容,会被操作系统暂存在输出缓冲区里,不会实时刷新到终端界面。直到整个下载流程执行完毕,缓冲区因为程序运行结束被强制清空,攒了很久的进度条内容才一次性显示出来,给人“晚了很久才启动”的错觉。
    这个问题可以通过以下方式解决:
    1. 每次更新进度条后强制刷新输出缓冲区,避免内容暂存:
      for data in resp.iter_content(chunk_size=1024):
          size = file.write(data)
          bar.update(size)
          bar.refresh() # 强制将当前进度推送到终端
      
    2. 不要把分块大小设得太小,当前代码用的chunk_size=1024(1KB)会导致循环频率过高,更容易触发缓冲堆积,调整为1MB分块可以大幅减少循环次数,降低缓冲压力:
      # 1MB为一个下载块,平衡下载速度和进度更新频率
      for data in resp.iter_content(chunk_size=1024 * 1024):
      
    3. 关闭Python的输出缓冲,二选一即可:
      • 运行程序时添加-u参数,比如python -u main.py
      • 代码开头加全局配置:
        import sys
        sys.stdout.reconfigure(line_buffering=True)
        

额外注意

下载带重定向的资源时,要确保requests默认的重定向跟随开关没有被关闭(allow_redirects=True是默认值,不要手动设为False),否则会拿到重定向跳转页的内容大小,而不是最终下载文件的真实大小,导致进度条计算偏差。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.23 02:54:04