import requests
from urllib.parse import urlparse
import os
import time
from tqdm import tqdm # 进度条库
# 安装依赖:pip install tqdm requests
# 目标下载链接
download_url = "https://dldir1.qq.com/qqfile/qq/PCQQ9.7.17/QQ9.7.17.29225.exe"
# 保存路径(Windows 示例,可改为其他路径)
save_dir = r"/Users/heha/Downloads"
os.makedirs(save_dir, exist_ok=True)
def download_file_with_progress(url, save_path):
try:
# 发送 HEAD 请求获取文件总大小
head_response = requests.head(url, allow_redirects=True, timeout=10)
total_size = int(head_response.headers.get("Content-Length", 0)) # 单位:字节
filename = get_filename_from_response(head_response, url)
full_path = os.path.join(save_path, filename)
# 发送 GET 请求并显示进度条
with requests.get(url, stream=True, allow_redirects=True, timeout=30) as response:
response.raise_for_status()
# 使用 tqdm 创建进度条
progress_bar = tqdm(
total=total_size,
unit="B",
unit_scale=True,
unit_divisor=1024,
desc=f"下载 {filename}",
bar_format="{l_bar}{bar}| {n_fmt}/{total_fmt} [{elapsed}<{remaining}, {rate_fmt}]"
)
start_time = time.time()
downloaded_size = 0
with open(full_path, "wb") as f:
for chunk in response.iter_content(chunk_size=8192):
if chunk:
f.write(chunk)
downloaded_size += len(chunk)
progress_bar.update(len(chunk)) # 更新进度条
# 计算下载速度和剩余时间
elapsed_time = time.time() - start_time
if elapsed_time > 0:
speed = downloaded_size / elapsed_time
remaining_size = total_size - downloaded_size
remaining_time = remaining_size / speed if speed != 0 else 0
progress_bar.set_postfix({
"速度": f"{speed / (1024 * 1024):.2f} MB/s",
"剩余时间": f"{remaining_time:.0f}s"
})
progress_bar.close() # 关闭进度条
print(f"\n✅ 下载完成:{full_path}")
except requests.exceptions.RequestException as e:
print(f"❌ 请求失败:{e}")
except Exception as e:
print(f"❌ 发生异常:{e}")
def get_filename_from_response(response, url):
"""提取并清洗文件名"""
content_disposition = response.headers.get("Content-Disposition", "")
filename = content_disposition.split("filename=")[1].strip(
'"') if "filename=" in content_disposition else os.path.basename(urlparse(url).path)
invalid_chars = r'<>:"/\\|?*'
for char in invalid_chars:
filename = filename.replace(char, "_")
return filename
if __name__ == "__main__":
download_file_with_progress(download_url, save_dir)
自己运行的话,需要对如下几个部分进行修改
1. download_url ( 改成自己的下载链接)
2. save_dir (改成自己需要存储的地址)