Ответ 1
Обновить: dnozay answer объясняет проблему и должен быть принятым ответом.
Попробуйте модуль gzip
, код ниже прямо из python docs.
import gzip
f = gzip.open('/home/joe/file.txt.gz', 'rb')
file_content = f.read()
f.close()
У меня есть файл gzip, и я пытаюсь прочитать его через Python, как показано ниже:
import zlib
do = zlib.decompressobj(16+zlib.MAX_WBITS)
fh = open('abc.gz', 'rb')
cdata = fh.read()
fh.close()
data = do.decompress(cdata)
он выдает эту ошибку:
zlib.error: Error -3 while decompressing: incorrect header check
Как я могу его преодолеть?
Обновить: dnozay answer объясняет проблему и должен быть принятым ответом.
Попробуйте модуль gzip
, код ниже прямо из python docs.
import gzip
f = gzip.open('/home/joe/file.txt.gz', 'rb')
file_content = f.read()
f.close()
У вас есть эта ошибка:
zlib.error: Error -3 while decompressing: incorrect header check
Что наиболее вероятно, потому что вы пытаетесь проверить заголовки, которых там нет, например, ваши данные следуют RFC 1951
(сжатый формат deflate
), а не RFC 1950
(сжатый формат zlib
) или RFC 1952
(сжатый формат gzip
).
Но zlib
может распаковать все эти форматы:
deflate
, используйте wbits = -zlib.MAX_WBITS
zlib
, используйте wbits = zlib.MAX_WBITS
gzip
, используйте wbits = zlib.MAX_WBITS | 16
wbits = zlib.MAX_WBITS | 16
См. Документацию в http://www.zlib.net/manual.html#Advanced (раздел inflateInit2
).
данные испытаний:
>>> deflate_compress = zlib.compressobj(9, zlib.DEFLATED, -zlib.MAX_WBITS)
>>> zlib_compress = zlib.compressobj(9, zlib.DEFLATED, zlib.MAX_WBITS)
>>> gzip_compress = zlib.compressobj(9, zlib.DEFLATED, zlib.MAX_WBITS | 16)
>>>
>>> text = '''test'''
>>> deflate_data = deflate_compress.compress(text) + deflate_compress.flush()
>>> zlib_data = zlib_compress.compress(text) + zlib_compress.flush()
>>> gzip_data = gzip_compress.compress(text) + gzip_compress.flush()
>>>
очевидный тест для zlib
:
>>> zlib.decompress(zlib_data)
'test'
тест на deflate
:
>>> zlib.decompress(deflate_data)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
zlib.error: Error -3 while decompressing data: incorrect header check
>>> zlib.decompress(deflate_data, -zlib.MAX_WBITS)
'test'
тест для gzip
:
>>> zlib.decompress(gzip_data)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
zlib.error: Error -3 while decompressing data: incorrect header check
>>> zlib.decompress(gzip_data, zlib.MAX_WBITS|16)
'test'
данные также совместимы с модулем gzip
:
>>> import gzip
>>> import StringIO
>>> fio = StringIO.StringIO(gzip_data) # io.BytesIO for Python 3
>>> f = gzip.GzipFile(fileobj=fio)
>>> f.read()
'test'
>>> f.close()
добавление 32
к windowBits
вызовет обнаружение заголовка
>>> zlib.decompress(gzip_data, zlib.MAX_WBITS|32)
'test'
>>> zlib.decompress(zlib_data, zlib.MAX_WBITS|32)
'test'
gzip
или вы можете игнорировать zlib
и напрямую использовать модуль gzip
; но, пожалуйста, помните, что под капотом gzip
использует zlib
.
fh = gzip.open('abc.gz', 'rb')
cdata = fh.read()
fh.close()
Я просто решил проблему с неправильной проверкой заголовка при распаковке gzipped-данных.
Вам нужно установить -WindowBits = > WANT_GZIP в свой призыв к inflateInit2 (используйте 2 версию)
Да, это может быть очень неприятно. Обычно мелкое чтение документации представляет Zlib как сжатие API для Gzip, но по умолчанию (не используя методы gz *) он не создает или не разжимает формат Gzip. Вы должны отправить этот не очень заметный документ.
Мой случай состоял в том, чтобы распаковать почтовые сообщения, которые хранятся в базе данных Bullhorn. Фрагмент следующий:
import pyodbc
import zlib
cn = pyodbc.connect('connection string')
cursor = cn.cursor()
cursor.execute('SELECT TOP(1) userMessageID, commentsCompressed FROM BULLHORN1.BH_UserMessage WHERE DATALENGTH(commentsCompressed) > 0 ')
for msg in cursor.fetchall():
#magic in the second parameter, use negative value for deflate format
decompressedMessageBody = zlib.decompress(bytes(msg.commentsCompressed), -zlib.MAX_WBITS)
Как ни странно, у меня была эта ошибка при попытке работать с API с помощью Python.
Мне удалось заставить его работать с объектом GzipFile
из каталога gzip, примерно так:
import gzip
gzip_file = gzip.GzipFile(fileobj=open('abc.gz', 'rb'))
file_contents = gzip_file.read()
Чтобы распаковать неполные сжатые байты, которые находятся в памяти, полезен ответ dnozay, но он пропускает вызов zlib.decompressobj
который я счел необходимым:
incomplete_decompressed_content = zlib.decompressobj(wbits=zlib.MAX_WBITS | 16).decompress(incomplete_gzipped_content)
Обратите внимание, что zlib.MAX_WBITS | 16
zlib.MAX_WBITS | 16
это 15 | 16
15 | 16
который равен 31. Для получения дополнительной информации о wbits
см. zlib.decompress
.
Кредит: ответ Яна Вернье, который отмечает вызов zlib.decompressobj
.
Просто добавьте заголовок "Accept-Encoding": "identity"
import requests
requests.get('http://gett.bike/', headers={'Accept-Encoding': 'identity'})