【问题标题】:How to download chunked data with Pythons urllib2如何使用 Python urllib2 下载分块数据
【发布时间】:2023-12-29 13:03:01
【问题描述】:

我正在尝试使用 Python 2 从服务器下载一个大文件:

req = urllib2.Request("https://myserver/mylargefile.gz")
rsp = urllib2.urlopen(req)
data = rsp.read()

服务器使用“Transfer-Encoding: chunked”发送数据,我只得到一些二进制数据,无法通过 gunzip 解包。

我必须遍历多个 read() 吗?还是多个请求?如果是这样,它们的外观如何?

注意:我正在尝试仅使用 Python 2 标准库来解决问题,而不使用 urllib3 或 requests 等其他库。这甚至可能吗?

【问题讨论】:

    标签: python download urllib2 chunked transfer-encoding


    【解决方案1】:

    来自 urllib2.urlopen 上的 python 文档:

    一个警告:read() 方法,如果省略 size 参数或 负数,直到数据流结束才能读取;没有 确定来自套接字的整个流的好方法 在一般情况下阅读。

    所以,循环读取数据:

    req = urllib2.Request("https://myserver/mylargefile.gz")
    rsp = urllib2.urlopen(req)
    data = rsp.read(8192)
    while data:
       # .. Do Something ..
       data = rsp.read(8192)
    

    【讨论】:

    • 我的印象是,这仅适用于下载未使用 transfer-encoding=chunked 发送的文件。
    • 嗯,你是对的。我看到了一个没有答案的类似问题:*.com/questions/15115606/… 抱歉,我不知道如何通过它。唯一的答案使用 curl。
    • 好的,我会尝试 curl,与 Python 相比,登录 cookie 有点麻烦,但总比没有好。谢谢!
    【解决方案2】:

    如果我没记错的话,以下内容对我有用 - 不久前:

    data = ''
    chunk = rsp.read()
    while chunk:
        data += chunk
        chunk = rsp.read()
    

    每个read 读取一个块 - 所以请继续阅读,直到没有更多内容出现。 还没有准备好支持这一点的文档……还没有。

    【讨论】:

    • 不幸的是,这对我不起作用: content = '' while True: chunk = rsp.read() if not chunk break content += chunk f.write(content)
    • does not work 不幸的是,这是一个非常无用的声明 :) 是否还有内容缺失?
    • 对不起:在“完全像以前一样”的意义上“不起作用”。 IE。数据不完整,gunzip 无法读取。我假设 urllib2 只是不支持分块传输编码。
    【解决方案3】:

    我也有同样的问题。

    我发现“Transfer-Encoding: chunked”经常与“Content-Encoding: gzip”。

    所以也许我们可以得到压缩的内容并解压它。

    它对我有用。

    import urllib2
    from StringIO import StringIO
    import gzip
    
    req = urllib2.Request(url)
    req.add_header('Accept-encoding', 'gzip, deflate')
    rsp = urllib2.urlopen(req)
    if rsp.info().get('Content-Encoding') == 'gzip':
        buf = StringIO(rsp.read())
        f = gzip.GzipFile(fileobj=buf)
        data = f.read()
    

    【讨论】:

      最近更新 更多