必须用 requests.get(url, stream=True) 配合 tqdm.iter_content() 实现流式下载,否则内存溢出或进度条失效;需检查 status_code、转换 content-length 为 int、设 unit="B" 和 unit_scale=True,并用 fp.write(chunk) 写入二进制文件。

直接用 requests 配合 tqdm 就能实现带进度条的文件下载,但必须手动处理流式响应和文件写入,否则进度条会卡在 0% 或提前结束。
为什么不能直接用 requests.get(url).content?
这样做会把整个响应体一次性加载进内存,既无法实时更新进度,又可能因大文件导致内存爆满。真正可行的方式是启用流式下载(stream=True),边接收边写入磁盘。
-
requests.get(url, stream=True)是必须的,否则response.iter_content()没意义 - 必须检查
response.status_code == 200,否则tqdm会按错误响应长度初始化进度条,显示异常 -
response.headers.get("content-length")可能为None(如服务器未返回该 header),此时需设total=None让tqdm显示不确定进度
如何正确使用 tqdm 绑定下载流?
tqdm 要包裹的是 response.iter_content(chunk_size) 迭代器,并将每次读取的 chunk 写入文件句柄。关键在于:进度条单位必须是字节(unit="B"),且 unit_scale=True 才能自动转成 KB/MB 显示。
- 推荐
chunk_size=8192(8KB),太小影响 I/O 效率,太大对内存压力无实质改善 - 写入时用
fp.write(chunk),不要用fp.writelines()—— 后者适用于行序列,而chunk是bytes - 务必在
with open(...)上下文中操作文件,避免中断后残留空文件
遇到重定向或认证时怎么保持进度条正常?
requests 默认跟随重定向,但重定向后的响应可能不带 Content-Length,导致进度条变成“未知长度”模式。若需认证,auth 参数不影响流式行为,但 token 类认证需加到 headers 中。
立即学习“Python免费学习笔记(深入)”;
- 若明确知道目标 URL 不重定向,可加
allow_redirects=False避免意外丢失Content-Length - Bearer Token 示例:
headers={"Authorization": "Bearer xxx"},放在requests.get()参数里即可 - 下载中途断连时,
tqdm会停止,但文件已写入部分保留——如需断点续传,得自己解析Range请求头并对比本地文件大小,这超出基础进度条范畴
最易被忽略的是 response.headers.get("content-length") 返回的是字符串,必须用 int() 转换;没做这步会导致 tqdm 初始化失败并抛 TypeError。另外 Windows 下路径含中文时,open() 必须显式指定 encoding=None(二进制模式)或用 mode="wb",否则写入乱码或报错。


















