如何用Python requests下载视频时显示实时下载进度
实现实时下载进度显示方案
要实现浏览器式的实时下载进度显示,你需要放弃直接使用shutil.copyfileobj复制流,改为分块读取响应内容,同时跟踪已下载字节数并实时输出进度。以下是修改后的完整代码:
import requests import sys print(f'[+] Downloading "{file}" ({sizeInMb} MB)...') with requests.get(url, stream=True) as r: # 从响应头获取总文件大小,兼容服务器不返回Content-Length的情况 total_size = int(r.headers.get('Content-Length', 0)) downloaded_size = 0 chunk_size = 1024 * 1024 # 每次读取1MB,可根据需求调整大小 with open(filePath, 'wb+') as f: for chunk in r.iter_content(chunk_size=chunk_size): if chunk: # 过滤空数据块 f.write(chunk) downloaded_size += len(chunk) # 构建进度文本 if total_size > 0: progress_text = f'已下载 {downloaded_size} 字节 / 总 {total_size} 字节' else: progress_text = f'已下载 {downloaded_size} 字节' # 用\r回到行首覆盖原有内容,flush确保实时输出 sys.stdout.write(f'\r{progress_text}') sys.stdout.flush() # 下载完成后换行,避免覆盖后续输出内容 print() print(f'[-] Downloaded "{file}".') downloadCount += 1
关键细节说明
stream=True:必须保留该参数,让requests分块接收响应,避免一次性将大文件加载到内存。chunk_size:控制每次读取的数据块大小,值越小进度更新越频繁,但会增加IO开销;值越大IO效率越高,进度更新间隔越长,可根据实际场景调整。- 总大小兼容处理:部分服务器不会返回
Content-Length响应头,此时仅显示已下载字节数即可。 - 单行实时更新:通过
\r让光标回到当前行开头,配合sys.stdout.flush()确保进度文本立即输出到终端,实现类似浏览器的实时刷新效果。
内容的提问来源于stack exchange,提问作者Aashif Ali
相关产品推荐
相关产品推荐

