我目前使用以下代码通过urllib2解压缩gzipped响应:
opener = urllib2.build_opener()
response = opener.open(req)
data = response.read()
if response.headers.get('content-encoding', '') == 'gzip':
data = StringIO.StringIO(data)
gzipper = gzip.GzipFile(fileobj=data)
html = gzipper.read()
它是否也能处理泄密的响应,还是需要编写单独的代码来处理泄密的响应?
答案 0 :(得分:4)
有一个更好的方法概述:
作者解释了如何通过块解压缩块,而不是在内存中一次解压缩块。当涉及较大的文件时,这是首选方法。
还找到了这个有用的测试网站:
答案 1 :(得分:4)
你可以尝试
if response.headers.get('content-encoding', '') == 'deflate':
html = zlib.decompress(response.read())
如果失败,这是另一种方式,我在requests source code,
中找到了它if response.headers.get('content-encoding', '') == 'deflate':
html = zlib.decompressobj(-zlib.MAX_WBITS).decompress(response.read())
答案 2 :(得分:1)
要回答上述评论,HTTP规范(http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.3)说:
如果请求中不存在Accept-Encoding字段,则服务器可以假定客户端将接受任何内容编码。在这种情况下,如果“身份”是可用内容编码之一,那么服务器应该使用“身份”内容编码,除非它具有不同内容编码对客户端有意义的附加信息。
我认为这意味着它应该使用身份。我从来没有见过没有的服务器。
答案 3 :(得分:1)
您可以在urllib3
中看到代码class DeflateDecoder(object):
def __init__(self):
self._first_try = True
self._data = binary_type()
self._obj = zlib.decompressobj()
def __getattr__(self, name):
return getattr(self._obj, name)
def decompress(self, data):
if not data:
return data
if not self._first_try:
return self._obj.decompress(data)
self._data += data
try:
return self._obj.decompress(data)
except zlib.error:
self._first_try = False
self._obj = zlib.decompressobj(-zlib.MAX_WBITS)
try:
return self.decompress(self._data)
finally:
self._data = None
class GzipDecoder(object):
def __init__(self):
self._obj = zlib.decompressobj(16 + zlib.MAX_WBITS)
def __getattr__(self, name):
return getattr(self._obj, name)
def decompress(self, data):
if not data:
return data
return self._obj.decompress(data)