使用请求通过 http 下载文件时的进度条

新手上路,请多包涵

我需要下载一个相当大的 (~200MB) 文件。我想出了如何在 这里 下载和保存文件。如果有一个进度条可以知道下载了多少,那就太好了。我找到了 ProgressBar 但我不确定如何将两者结合在一起。

这是我试过的代码,但没有用。

 bar = progressbar.ProgressBar(max_value=progressbar.UnknownLength)
with closing(download_file()) as r:
    for i in range(20):
        bar.update(i)

原文由 Gamegoofs2 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 692
2 个回答

我建议你试试 tqdm ,它非常容易使用。使用 requests 库下载的示例代码:

 from tqdm import tqdm
import requests

url = "http://www.ovh.net/files/10Mb.dat" #big file test
# Streaming, so we can iterate over the response.
response = requests.get(url, stream=True)
total_size_in_bytes= int(response.headers.get('content-length', 0))
block_size = 1024 #1 Kibibyte
progress_bar = tqdm(total=total_size_in_bytes, unit='iB', unit_scale=True)
with open('test.dat', 'wb') as file:
    for data in response.iter_content(block_size):
        progress_bar.update(len(data))
        file.write(data)
progress_bar.close()
if total_size_in_bytes != 0 and progress_bar.n != total_size_in_bytes:
    print("ERROR, something went wrong")

原文由 leovp 发布,翻译遵循 CC BY-SA 4.0 许可协议

tqdm 包现在包含一个更专门为此类情况设计的函数: wrapattr 。您只需包装一个对象的 read (或 write )属性,其余的由 tqdm 处理;没有搞乱块大小或类似的东西。这是一个简单的下载函数,将其与 requests 放在一起:

 def download(url, filename):
    import functools
    import pathlib
    import shutil
    import requests
    from tqdm.auto import tqdm

    r = requests.get(url, stream=True, allow_redirects=True)
    if r.status_code != 200:
        r.raise_for_status()  # Will only raise for 4xx codes, so...
        raise RuntimeError(f"Request to {url} returned status code {r.status_code}")
    file_size = int(r.headers.get('Content-Length', 0))

    path = pathlib.Path(filename).expanduser().resolve()
    path.parent.mkdir(parents=True, exist_ok=True)

    desc = "(Unknown total file size)" if file_size == 0 else ""
    r.raw.read = functools.partial(r.raw.read, decode_content=True)  # Decompress if needed
    with tqdm.wrapattr(r.raw, "read", total=file_size, desc=desc) as r_raw:
        with path.open("wb") as f:
            shutil.copyfileobj(r_raw, f)

    return path

原文由 Mike 发布,翻译遵循 CC BY-SA 4.0 许可协议

推荐问题