请求 Gzip HTTP 下载并写入磁盘

jax*_*xas 4 gzip http zlib python-2.7 python-requests

我正在使用请求库和 python 2.7 从 web api 下载 gzip 文本文件。使用下面的代码,我能够成功发送一个 get 请求,并从标头判断,以 gzip 文件的形式接收响应。

我知道如果请求从头中检测到响应被 gzip 压缩,它会自动为您解压缩这些文件。我想以文件流的形式进行下载,并将内容写入磁盘以供存储和未来分析。

当我在我的工作目录中打开结果文件时,我得到这样的字符:—}}¶— Q@Ï 'õ

作为参考,一些响应头包括 'Content-Encoding': 'gzip', 'Content-Type': 'application/download', 'Accept-Encoding,User-Agent'

我用二进制写错了吗?我是否没有正确编码文本(即它可能是 ASCII 还是 utf-8)?响应标头中没有注明明显的字符编码。

try:
    response = requests.get(url, paramDict, stream=True)
except Exception as e:
    print(e)

with open(outName, 'wb') as out_file:
    for chunk in response.iter_content(chunk_size=1024):
        out_file.write(chunk)
Run Code Online (Sandbox Code Playgroud)

编辑 3.30.2016:现在我稍微改变了我的代码以利用 gzipstream 库。我尝试使用流读取响应内容中的整个 Gzipped 文本文件:

with open(outName, 'wb') as out_file, GzipStreamFile(response.content) as fileStream:
    streamContent = fileStream.read()
    out_file.write(streamContent)
Run Code Online (Sandbox Code Playgroud)

然后我收到了这个错误:out_file.write(streamContent) AttributeError: '_GzipStreamFile' object has no attribute 'close'

输出是一个空文本文件,文件名符合预期。我是否需要在with块外初始化我的 streamContent 变量,以便它不会在块的末尾自动尝试调用 close 方法?

编辑 4.1.2016只是想我会澄清这不一定是流,这只是我遇到的一个解决方案。我只想每天请求这个 gzipped 文件,并将其以纯文本格式保存在本地

jax*_*xas 7

try:
    response = requests.get(url, paramDict)
except Exception as e:
    print(e)

data = zlib.decompress(response.content, zlib.MAX_WBITS|32)

with open('outFileName.txt','w') as outFile:
    outFile.write(data)
Run Code Online (Sandbox Code Playgroud)

这是我编写的最终工作的代码。正如 sigmavirus 所说:文件一开始就被压缩了。我知道这个事实,但没有足够清楚地描述它,因为我一直在读/写压缩后的字节。

使用 zlib 模块,我能够一次性将响应的内容全部解压到数据变量中;然后我将包含解压缩数据的变量写入文件。

我不确定这是否是最好的或最 Pythonic 的方法,但它有效。如果有人能启发我为什么我不能提供gzip.open这个内容(也许我需要使用另一种方法,我尝试了 gzipstream 库无济于事),我希望得到任何解释,但我确实认为这个问题得到了回答。

感谢所有帮助过我的人,即使你们没有解决办法,也是你们的帮助鼓励我坚持下去!