本文目录导读:

- 方法1:使用requests库(最常用)
- 方法2:不使用第三方库(纯手工制作进度条)
- 方法3:使用urllib(标准库)
- 方法4:使用wget库(更简单)
- 方法5:使用rich库(美观的进度条)
- 完整示例:带错误处理和断点续传
- 安装依赖
- 选择建议
在Python中下载大文件并显示进度,有多种方法,以下是几种常用的实现方案:
方法1:使用requests库(最常用)
import requests
from tqdm import tqdm
def download_file_with_progress(url, filename):
response = requests.get(url, stream=True)
response.raise_for_status()
# 获取文件大小(字节)
total_size = int(response.headers.get('content-length', 0))
# 设置进度条
progress_bar = tqdm(total=total_size, unit='B', unit_scale=True, desc=filename)
with open(filename, 'wb') as file:
for chunk in response.iter_content(chunk_size=8192):
if chunk:
file.write(chunk)
progress_bar.update(len(chunk))
progress_bar.close()
# 使用示例
url = "https://example.com/large-file.zip"
download_file_with_progress(url, "large-file.zip")
方法2:不使用第三方库(纯手工制作进度条)
import requests
import sys
def download_file_custom_progress(url, filename):
response = requests.get(url, stream=True)
response.raise_for_status()
total_size = int(response.headers.get('content-length', 0))
downloaded = 0
with open(filename, 'wb') as file:
for chunk in response.iter_content(chunk_size=8192):
if chunk:
file.write(chunk)
downloaded += len(chunk)
# 显示进度
if total_size > 0:
percent = downloaded / total_size * 100
bar_length = 50
filled = int(bar_length * downloaded // total_size)
bar = '█' * filled + '░' * (bar_length - filled)
sys.stdout.write(f'\r{bar} {percent:.1f}% ({downloaded}/{total_size} bytes)')
sys.stdout.flush()
print() # 换行
# 使用示例
download_file_custom_progress("https://example.com/large-file.zip", "large-file.zip")
方法3:使用urllib(标准库)
import urllib.request
import sys
def download_with_urllib(url, filename):
def report_hook(block_num, block_size, total_size):
downloaded = block_num * block_size
if total_size > 0:
percent = min(downloaded / total_size * 100, 100)
bar_length = 50
filled = int(bar_length * downloaded // total_size)
bar = '█' * filled + '░' * (bar_length - filled)
sys.stdout.write(f'\r{bar} {percent:.1f}% ({downloaded}/{total_size} bytes)')
sys.stdout.flush()
urllib.request.urlretrieve(url, filename, reporthook=report_hook)
print() # 换行
# 使用示例
download_with_urllib("https://example.com/large-file.zip", "large-file.zip")
方法4:使用wget库(更简单)
# 首先安装:pip install wget
import wget
def download_with_wget(url, filename):
wget.download(url, out=filename)
print() # wget会自动显示进度条
# 使用示例
download_with_wget("https://example.com/large-file.zip", "large-file.zip")
方法5:使用rich库(美观的进度条)
# 首先安装:pip install rich
import requests
from rich.progress import Progress
def download_with_rich(url, filename):
response = requests.get(url, stream=True)
response.raise_for_status()
total_size = int(response.headers.get('content-length', 0))
with Progress() as progress:
task = progress.add_task("[cyan]Downloading...", total=total_size)
with open(filename, 'wb') as file:
for chunk in response.iter_content(chunk_size=8192):
if chunk:
file.write(chunk)
progress.update(task, advance=len(chunk))
# 使用示例
download_with_rich("https://example.com/large-file.zip", "large-file.zip")
完整示例:带错误处理和断点续传
import requests
from tqdm import tqdm
import os
def download_with_resume(url, filename):
# 检查已下载部分
downloaded = 0
if os.path.exists(filename):
downloaded = os.path.getsize(filename)
# 设置请求头,支持断点续传
headers = {'Range': f'bytes={downloaded}-'} if downloaded > 0 else {}
response = requests.get(url, stream=True, headers=headers)
response.raise_for_status()
# 获取总文件大小
total_size = int(response.headers.get('content-length', 0))
if downloaded > 0:
total_size += downloaded
mode = 'ab' if downloaded > 0 else 'wb'
with open(filename, mode) as file:
with tqdm(total=total_size, initial=downloaded, unit='B',
unit_scale=True, desc=filename) as pbar:
for chunk in response.iter_content(chunk_size=8192):
if chunk:
file.write(chunk)
pbar.update(len(chunk))
# 使用示例
download_with_resume("https://example.com/large-file.zip", "large-file.zip")
安装依赖
# 基础版本 pip install requests tqdm # 如果使用rich pip install rich # 如果使用wget pip install wget
选择建议
- 简单快速:使用
wget库 - 最常用:
requests+tqdm组合 - 无需第三方库:使用
urllib标准库 - 美观显示:使用
rich库 - 需要断点续传:使用带
Range头的定制版本
推荐使用第一种方法(requests + tqdm),它既简单又功能完善。