python - 使用 gzip 编码分块下载大文件 (Python 3.4)

标签 python python-3.x urllib2 urllib chunked-encoding

如果我请求一个文件并指定 gzip 编码,我该如何处理?

通常当我有一个大文件时,我会执行以下操作:

while True:
   chunk = resp.read(CHUNK)
   if not chunk: break
   writer.write(chunk)
   writer.flush()

其中 CHUNK 是以字节为单位的大小,writer 是一个 open() 对象,resp 是从 urllib 请求生成的请求响应。

所以大多数情况下,当响应 header 包含“gzip”作为返回编码时,这很简单,我会执行以下操作:

decomp = zlib.decompressobj(16+zlib.MAX_WBITS)
data = decomp.decompress(resp.read())
writer.write(data)
writer.flush()

或者这个:

f = gzip.GzipFile(fileobj=buf)
writer.write(f.read())

其中 buf 是一个 BytesIO()。

如果我尝试解压缩 gzip 响应,我会遇到问题:

while True:
   chunk = resp.read(CHUNK)
   if not chunk: break
   decomp = zlib.decompressobj(16+zlib.MAX_WBITS)
   data = decomp.decompress(chunk)
   writer.write(data)
   writer.flush()

有什么方法可以解压缩 gzip 数据,因为它会分成小块?还是我需要将整个文件写入磁盘,解压缩然后将其移动到最终文件名?使用 32 位 Python 时,我遇到的部分问题是我可能会遇到内存不足错误。

谢谢

最佳答案

我想我找到了一个我想分享的解决方案。

def _chunk(response, size=4096):
     """ downloads a web response in pieces """
    method = response.headers.get("content-encoding")
    if method == "gzip":
        d = zlib.decompressobj(16+zlib.MAX_WBITS)
        b = response.read(size)
        while b:
            data = d.decompress(b)
            yield data
            b = response.read(size)
            del data
    else:
        while True:
            chunk = response.read(size)
            if not chunk: break
            yield chunk

如果谁有更好的解决方案,欢迎补充。基本上我的错误是创建了 zlib.decompressobj()。我在错误的地方创建它。

这似乎也适用于 python 2 和 3,所以有一个优点。

关于python - 使用 gzip 编码分块下载大文件 (Python 3.4),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34632521/

相关文章:

python - 加密柱状转置密码

python - 在 Python 中使用 numpy.random.choice 更快的替代方案?

python-3.x - 如何缓存异步协程

python - 将 Google 搜索返回到 Python

python - Django api 返回模型 ID 而不是模型的标题

Python ReportLab 设置背景色

python - 如何巧妙地为大量变量分配相同的值?

python - 在 python 中使用 Syntaxnet POS 标签?

python - 使用多个线程下载单个文件

python - 如何通过 urllib2 发送 HTTP/1.0 请求?