【问题标题】:Python 3 and requests with a progressbarPython 3 和带有进度条的请求
【发布时间】:2012-05-18 12:45:46
【问题描述】:

我正在尝试使用 python 请求下载文件。它在 python 2.7 中工作,但现在不行。我真的很困惑,必须有一个更简单的答案。由于文件可能非常大,我真的想要一个进度条,我正在使用 python progressbar 来完成这项工作。

                r = requests.get(file_url, data={'track': 'requests'})
                size = int(r.headers['Content-Length'].strip())
                self.bytes = 0
                widgets = [name, ": ", Bar(marker="|", left="[", right=" "),
                    Percentage(), " ",  FileTransferSpeed(), "] ",
                    self,
                    " of {0}MB".format(round(size / 1024 / 1024, 2))]
                pbar = ProgressBar(widgets=widgets, maxval=size)
                pbar.start()

                file = b""
                for chunk in r.iter_content()
                    if chunk:
                        file += chunk

                        self.bytes += 1
                        pbar.update(self.bytes)

我发现使用 iter_content 是获得持续更新的最佳方式。我确实尝试过 iter_lines 但它弄乱了文件。它突然停止下载并且真的很慢,下载 10% 需要 15 分钟,然后停止。并且尝试以字节模式打开文件并写入它是行不通的,它根本不会引发错误。当我尝试使用

打印块包含的内容时
print(chunk.decode("utf-8")

有效,但只有几个字符。在某些时候它抱怨

UnicodeDecodeError: 'utf8' codec can't decode byte 0xff in position 0: invalid start byte

即使在 iter_content 中使用“decode_unicode=True”也无济于事。我很困惑,不知道该怎么办。使用 Py3k 应该没那么难。

【问题讨论】:

    标签: python python-3.x request progress-bar chunks


    【解决方案1】:

    设法修复它。所以这里是更新的代码:

    r = requests.get(file_url)
    size = int(r.headers['Content-Length'].strip())
    self.bytes = 0
    widgets = [name, ": ", Bar(marker="|", left="[", right=" "),
        Percentage(), " ",  FileTransferSpeed(), "] ",
        self,
        " of {0}MB".format(str(round(size / 1024 / 1024, 2))[:4])]
    pbar = ProgressBar(widgets=widgets, maxval=size).start()
    file = []
    for buf in r.iter_content(1024):
        if buf:
            file.append(buf)
            self.bytes += len(buf)
            pbar.update(self.bytes)
    pbar.finish()
    

    下载速度从 7kb/s 变为 400+ kb/s。而且它完全正常工作。

    【讨论】:

    • 这难道不是将它写入文件的进度条吗?当您调用 requests.get() 时看到请求已完成?
    • requests.get() 函数返回一个 Response 对象。它实际上并没有做任何事情,除非你用它做点什么(比如 r = requests.get(file_url); r.text)。我在下载内容时对其进行了迭代。之后我实际上不得不将它保存到一个文件中:)
    • @thabubble 实际上,您需要致电requests.get(file_url, prefetch=False) 才能使您的陈述属实。否则,@antihero 是完全正确的。
    • 好吧,那我不知道它为什么会起作用。但确实如此。据我所知,我所做的是“r = self.s.get(file_url, data={'track': 'requests'})”,然后使用“for char in r.iter_content(): “而且它确实有效。你可以看到它下载。但这是很久以前的事了,我可能有错误的文件。但是在我发布答案后,它被很好地编辑了。我记得它只会下载标题,而不是正文。为此,您必须使用 r.text 或 r.iter_content()。
    猜你喜欢
    • 2020-04-20
    • 2010-10-29
    • 1970-01-01
    • 1970-01-01
    • 2013-10-08
    • 2015-03-31
    • 1970-01-01
    • 2010-10-22
    • 1970-01-01
    相关资源
    最近更新 更多