Python脚本下载大文件如何显示进度

wen 实用脚本 1

本文目录导读:

Python脚本下载大文件如何显示进度

  1. 方法1:使用requests库(最常用)
  2. 方法2:不使用第三方库(纯手工制作进度条)
  3. 方法3:使用urllib(标准库)
  4. 方法4:使用wget库(更简单)
  5. 方法5:使用rich库(美观的进度条)
  6. 完整示例:带错误处理和断点续传
  7. 安装依赖
  8. 选择建议

在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),它既简单又功能完善。

抱歉,评论功能暂时关闭!