如何让TQDM进度条在KB和MB之间自动更新

3

我有一个简单的 tqdm 进度条和 requests 模块结合使用的代码,用于下载文件:

import requests
from tqdm import tqdm

def download_to_file(path: str, filename: str, url: str):
    try:
        r = requests.get(url, stream=True)
        file_length = int(r.headers['Content-Length'])
        chunk_size = 1024  # 1MB
        num_bars = int(file_length / chunk_size)

        if r.status_code == 200:
            with open(f'{path}\\{filename}', 'wb+') as f:
                pbar = tqdm(total=num_bars, unit='B', unit_scale=True, desc=filename, leave=False, file=sys.stdout,
                            unit_divisor=1024)
                for chunk in r.iter_content(chunk_size=chunk_size):
                    if chunk:
                        pbar.update()
                        f.write(chunk)
        else:
            raise requests.HTTPError(f'Status code is {r.status_code}')
    except Exception as ex:
        print(f'[-] Failed to download \'{filename}\'! {str(ex)}')
        pass

这个功能可以运行,但是进度条的显示为 file.extension: 100%|████████████▉| 123k/123k [00:58<00:00, 2.87kB/s],问题在于123MB的文件被显示成了123k,并且当前速度也以KB/s为单位显示。我已经尝试过将单位改为KB,但这只会导致速度变成2.87kKB/s,实际上应该是MB/s。 我尝试查找使用tqdm库的GitHub存储库,但无法找到我想要的示例。请问如何使它显示总大小为123MB,当超过1000时,速度从KB/s更改为MB/s?

1个回答

1
这是相当陈旧的,但我刚好也需要做同样的事情。 我使用 pbar = tqdm(total=num_bars, unit="bytes", unit_scale=True, unit_divisor=1024) 来制作我的进度条并其结果为 3%|▎ | 9.00M/282M [00:02<01:01, 4.69Mbytes/s] (该文件大小是正确的) 所以我猜你不应该将 file_length 除以 chunk_size,因为 total 是期望迭代的次数,tqdm会自动调整单位。
我希望你或下一个人会发现这个有用。

抱歉,但是和 OP 发布的有什么区别呢?我猜在 num_bars 中你放了 file_length,但如果你按 1000 字节一块进行加载,那将会产生错误的加载进度条,因为你会告诉 tqdm 你需要 1000 倍的迭代次数。 - Frotaur
不同之处在于file_length没有被chunk_size除以得到num_bars,正如我所写的" total是预期迭代次数,tqdm会自动调整单位"。 - gs202
如果您按“chunk_size”加载块,则预期迭代次数正好为文件长度/ chunk_size。如果将文件长度提供为总迭代次数,则会因 chunk_size 的因素而出现错误,从而提供错误的加载栏。我是否遗漏了什么?当 chunk_size=1000 时,在文件大小正确的情况下,它将期望比所需多进行1000次迭代。 - Frotaur

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接