В Python, как мне декодировать кодировку GZIP? - PullRequest
38 голосов
/ 23 апреля 2010

Я загрузил веб-страницу в своем скрипте Python.В большинстве случаев это работает нормально.

Однако у этого был заголовок ответа: кодировка GZIP, и когда я попытался напечатать исходный код этой веб-страницы, в моей замазке были все символы.

Как декодировать это в обычный текст?

Ответы [ 7 ]

78 голосов
/ 23 апреля 2010

Я использую zlib для распаковки сжатого содержимого из Интернета.

import zlib

...
# f=urllib2.urlopen(url) 
decompressed_data=zlib.decompress(f.read(), 16+zlib.MAX_WBITS)
30 голосов
/ 23 апреля 2010

Распакуйте поток байтов с помощью встроенного модуля gzip.

Если у вас возникли проблемы, покажите точный минимальный код, который вы использовали, точное сообщение об ошибке и трассировку, а также результат print repr(your_byte_stream[:100])

Дополнительная информация

1. Чтобы узнать о путанице в gzip / zlib / deflate, прочитайте раздел «Прочее использование» этой статьи Википедии .

2. Может быть проще использовать модуль zlib, чем модуль gzip, если у вас есть строка, а не файл. К сожалению, документы Python неполные / неправильные:

""» zlib.decompress (string [, wbits [, bufsize]]) ... Абсолютное значение wbits является основанием два логарифма размера буфера истории («размер окна»), используемого при сжатии данных. Его абсолютное значение должно быть от 8 до 15 для самых последних версий библиотеки zlib, большие значения приводят к лучшему сжатию за счет большего использования памяти. Значение по умолчанию равно 15. Когда wbits отрицателен, стандартный заголовок gzip подавляется; это недокументированная функция библиотеки zlib, используемая для совместимости с форматом сжатого файла unzip. "" "

Во-первых, 8 <= log2_window_size <= 15 со значением, приведенным выше. Тогда то, что должно быть отдельным аргументом, помещается сверху: </p>

arg == log2_window_size означает, что предполагается, что строка имеет формат zlib (RFC 1950; то, что в HTTP 1.1 RFC 2616 вводит в заблуждение «deflate»).

arg == -log2_window_size означает, что предполагается, что строка в формате deflate (RFC 1951; что на самом деле реализовали люди, которые не читали RFC HTTP 1.1)

arg == 16 + log_2_window_size означает, что предполагается, что строка в формате gzip (RFC 1952). Таким образом, вы можете использовать 31.

Приведенная выше информация документирована в руководстве по библиотеке zlib C ... Ctrl-F для поиска windowBits.

11 голосов
/ 23 апреля 2010

Я использую что-то подобное:

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
8 голосов
/ 18 июля 2011

для Python 3

Попробуйте это:

import gzip

fetch = opener.open(request) # basically get a response object
data = gzip.decompress(fetch.read())
data = str(data,'utf-8')
2 голосов
/ 04 августа 2014

Аналогично ответу Шату для 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())

Этот метод позволяет обернуть gzip.decompress () в попытку / за исключением захвата и передачи OSError, что приводит к ситуациям, когда вы можете получить смешанные сжатые и несжатые данные. Некоторые небольшие строки на самом деле становятся больше, если они закодированы, поэтому вместо них отправляются простые данные.

1 голос
/ 26 февраля 2019

Если вы используете модуль Requests, то вам не нужно использовать другие модули , потому что gzip и deflate кодировки для передачи автоматически декодируются для вас.

Пример:

>>> 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,...

Свойство .text ответа предназначено для чтения содержимого в контексте text .

Свойство .content ответа предназначено для чтения содержимого в контексте binary .

См. Раздел Двоичный ответ на docs.python-requests.org

0 голосов
/ 21 марта 2013

Вы можете использовать urllib3 для простого декодирования gzip.

urllib3.response.decode_gzip(response.data)
...