在Python中,如何解码GZIP编码?

dced5bon  于 2023-05-05  发布在  Python
关注(0)|答案(9)|浏览(353)

我在我的python脚本中下载了一个网页。在大多数情况下,这工作得很好。
但是,这一个有一个响应头:GZIP编码,当我试图打印这个网页的源代码时,它在我的腻子中有所有的符号。
如何将其解码为常规文本?

ngynwnxp

ngynwnxp1#

我使用zlib来解压缩来自web的gzip内容。

import zlib
import urllib

f=urllib.request.urlopen(url) 
decompressed_data=zlib.decompress(f.read(), 16+zlib.MAX_WBITS)
mlnl4t2r

mlnl4t2r2#

使用内置的gzip模块解压缩字节流。
如果您遇到任何问题,请显示您使用的确切的最小代码、确切的错误消息和回溯,以及print repr(your_byte_stream[:100])的结果。

更多信息
**1.**有关gzip/zlib/deflate混淆的解释,请阅读this Wikipedia article的“其他用途”部分。
**2.**如果你有一个字符串而不是一个文件,使用zlib模块比使用gzip模块更容易。不幸的是,Python文档不完整/错误:

zlib.decompress(string[,wbits[,bufsize]])
wbits的绝对值是压缩数据时使用的历史缓冲区大小(“窗口大小”)的以2为底的对数。对于zlib库的最新版本,它的绝对值应该在8到15之间,值越大,压缩效果越好,但内存使用量越大。默认值为15。当wbits为负时,将抑制标准gzip头;这是zlib库的一个未记录的特性,用于与unzip的压缩文件格式兼容。
首先,8〈= log2_window_size〈= 15,具有上面给出的含义。然后,应该是一个单独的arg的东西被拼凑在上面:
arg == log2_window_size表示假设字符串为zlib格式(RFC 1950;HTTP 1.1 RFC 2616混淆地称为“deflate”)。
arg == -log2_window_size表示假设字符串为deflate格式(RFC 1951;没有仔细阅读HTTP 1.1 RFC的人实际上实现了什么)
arg == 16 + log_2_window_size表示假设字符串为gzip格式(RFC 1952)。你可以使用31。
以上信息记录在zlib C library manual...Ctrl-F搜索windowBits

olqngx59

olqngx593#

对于Python 3
试试这个:

import gzip

fetch = opener.open(request) # basically get a response object
data = gzip.decompress(fetch.read())
data = str(data,'utf-8')
s2j5cfk0

s2j5cfk04#

我用这样的东西:

f = urllib2.urlopen(request)
data = f.read()
try:
    from cStringIO import StringIO
    from gzip import GzipFile
    data2 = GzipFile('', 'r', 0, StringIO(data)).read()
    data = data2
except:
    #print "decompress error %s" % err
    pass
return data
mwngjboj

mwngjboj5#

如果您使用Requests模块,那么您不需要使用任何其他模块,因为gzipdeflate * transfer-encoding*会自动为您解码

  • 示例:*
>>> import requests
>>> custom_header = {'Accept-Encoding': 'gzip'}
>>> response = requests.get('https://api.github.com/events', headers=custom_header)
>>> response.headers
{'Content-Encoding': 'gzip',...}
>>> response.text
'[{"id":"9134429130","type":"IssuesEvent","actor":{"id":3287933,...
  • response* 的.text属性用于阅读 text 上下文中的内容。
  • response* 的.content属性用于阅读 binary 上下文中的内容。

请参见docs.python-requests.org上的“二进制响应内容”部分

f87krz0w

f87krz0w6#

和沙图对python3的回答差不多,只是排列方式有些不同:

import gzip

s = Request("https://someplace.com", None, headers)
r = urlopen(s, None, 180).read()
try: r = gzip.decompress(r)
except OSError: pass
result = json_load(r.decode())

这个方法允许在try/except中 Package gzip.decompress(),以捕获和传递OSError,这会导致您可能会得到混合的压缩和未压缩数据的情况。一些小的字符串如果被编码实际上会变大,所以发送的是纯数据。

fnx2tebb

fnx2tebb7#

这个版本很简单,通过不调用read()方法避免了先阅读整个文件。它提供了一个类似对象的文件流,而它的行为就像一个普通的文件流。

import gzip
from urllib.request import urlopen

my_gzip_url = 'http://my_url.gz'
my_gzip_stream = urlopen(my_gzip_url)
my_stream = gzip.open(my_gzip_stream, 'r')
bgibtngc

bgibtngc8#

使用Python 3,这些答案都不是现成的。下面是我获取页面并解码gzip响应的方法:

import requests
import gzip

response = requests.get('your-url-here')
data = str(gzip.decompress(response.content), 'utf-8')
print(data)  # decoded contents of page
fxnxkyjh

fxnxkyjh9#

你可以使用urllib3来轻松地解码gzip。

urllib3.response.decode_gzip(response.data)

相关问题