[英]How to decode the gzip compressed data returned in a HTTP Response in python?
我在 python 中创建了一个客户端/服务器架构,我从客户端获取 HTTP 请求,通过我的代码请求另一个 HTTP 服务器来提供服务。
当我从第三台服务器得到响应时,我无法解码 gzip 压缩数据,我首先使用\\r\\n
作为分隔符分割响应数据,这让我将数据作为列表中的最后一项,然后我尝试解压缩它与
zlib.decompress(data[-1])
但它给了我一个错误标题的错误。 我应该如何解决这个问题?
代码
client_reply = ''
while 1:
chunk = server2.recv(512)
if len(chunk) :
client.send(chunk)
client_reply += chunk
else:
break
client_split = client_reply.split("\r\n")
print client_split[-1].decode('zlib')
我想读取在客户端和第二个服务器之间传输的数据。
指定wbits
使用时zlib.decompress(string, wbits, bufsize)
请参阅“问题解答”例如结束。
让我们从一个 curl 命令开始,该命令下载一个字节范围响应,其中包含一个未知的“内容编码”(注意:我们事先知道它是某种压缩的东西,mabye deflate
可能是gzip
):
export URL="https://commoncrawl.s3.amazonaws.com/crawl-data/CC-MAIN-2016-18/segments/1461860106452.21/warc/CC-MAIN-20160428161506-00007-ip-10-239-7-51.ec2.internal.warc.gz"
curl -r 266472196-266527075 $URL | gzip -dc | tee hello.txt
使用以下响应标头:
HTTP/1.1 206 Partial Content
x-amz-id-2: IzdPq3DAPfitkgdXhEwzBSwkxwJRx9ICtfxnnruPCLSMvueRA8j7a05hKr++Na6s
x-amz-request-id: 14B89CED698E0954
Date: Sat, 06 Aug 2016 01:26:03 GMT
Last-Modified: Sat, 07 May 2016 08:39:18 GMT
ETag: "144a93586a13abf27cb9b82b10a87787"
Accept-Ranges: bytes
Content-Range: bytes 266472196-266527075/711047506
Content-Type: application/octet-stream
Content-Length: 54880
Server: AmazonS3
所以说到点子上了。
让我们显示前 10 个字节的十六进制输出: curl -r 266472196-266472208 $URL | xxd
curl -r 266472196-266472208 $URL | xxd
十六进制输出:
0000000: 1f8b 0800 0000 0000 0000 ecbd eb
我们可以看到我们正在使用十六进制值的一些基础知识。
大致意思是它可能是一个gzip( 1f8b
用放气() 0800
),不需修改时间( 0000 0000
),或任何额外的标志集( 00
),采用FAT32系统( 00
)。
请参阅第 2.3 / 2.3.1 节: https : //tools.ietf.org/html/rfc1952#section-2.3.1
所以到python上:
>>> import requests
>>> url = 'https://commoncrawl.s3.amazonaws.com/crawl-data/CC-MAIN-2016-18/segments/1461860106452.21/warc/CC-MAIN-20160428161506-00006-ip-10-239-7-51.ec2.internal.warc.gz'
>>> response = requests.get(url, params={"range":"bytes=257173173-257248267"})
>>> unknown_compressed_data = response.content
注意到任何类似的东西吗?:
>>> unknown_compressed_data[:10]
'\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x00'
关于解压,让我们根据(文档)随机尝试:
>>> import zlib
“zlib.error:准备解压缩数据时出错-2:不一致的流状态” :
>>> zlib.decompress(unknown_compressed_data, -31)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
zlib.error: Error -2 while preparing to decompress data: inconsistent stream state
“解压缩数据时出错 -3:不正确的标头检查”:
>>> zlib.decompress(unknown_compressed_data)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
zlib.error: Error -3 while decompressing data: incorrect header check
“zlib.error:解压缩数据时出现错误-3:无效距离太远” :
>>> zlib.decompress(unknown_compressed_data, 30)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
zlib.error: Error -3 while decompressing data: invalid distance too far back
>>> zlib.decompress(unknown_compressed_data, 31)
'WARC/1.0\r\nWARC-Type: response\r\nWARC-Date: 2016-04-28T20:14:16Z\r\nWARC-Record-ID: <urn:uu
根据https://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html ,标题和正文由仅包含 CRLF 字符的空行分隔。 你可以试试
client_split = client_reply.split("\r\n\r\n",1)
print client_split[1].decode('zlib')
拆分找到空行,附加参数限制拆分的数量 - 结果是包含两个项目,标题和正文的数组。 但是如果不了解更多关于您的代码和被拆分的实际字符串的信息,就很难推荐任何东西。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.