zlib.error: Ошибка -3 при распаковке: неверная проверка заголовка - PullRequest
46 голосов
/ 26 июня 2010

У меня есть файл 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

Как мне ее преодолеть?

Ответы [ 7 ]

96 голосов
/ 11 марта 2014

У вас есть эта ошибка:

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

См. Документацию в 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()

автоматическое определение заголовка (zlib или gzip)

добавление 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()
3 голосов
/ 11 июня 2013

Я только что решил проблему «некорректной проверки заголовка» при распаковке сжатых данных.

Вам нужно установить -WindowBits => WANT_GZIP при вызове inflateInit2 (используйте версию 2)

Да, это может быть очень неприятно. Обычно поверхностное чтение документации представляет Zlib как API для сжатия Gzip, но по умолчанию (без использования методов gz *) он не создает и не распаковывает формат Gzip. Вы должны отправить этот не очень заметный задокументированный флаг.

3 голосов
/ 26 июня 2010

Обновление : Ответ dnozay объясняет проблему и должен быть принятым ответом.


Попробуйте модуль gzip, приведенный ниже код взят прямо из документов Python .

import gzip
f = gzip.open('/home/joe/file.txt.gz', 'rb')
file_content = f.read()
f.close()
1 голос
/ 23 сентября 2015

Мой случай состоял в том, чтобы распаковать электронные письма, которые хранятся в базе данных 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)
0 голосов
/ 23 июня 2019

Для распаковки неполных сжатых байтов, находящихся в памяти, полезен ответ от dnozay , но он пропускает вызов zlib.decompressobj, который я счел необходимым:

incomplete_decompressed_content = zlib.decompressobj(wbits=zlib.MAX_WBITS | 16).decompress(incomplete_gzipped_content)

Примечаниечто zlib.MAX_WBITS | 16 равно 15 | 16, что составляет 31. Для некоторой предыстории о wbits см. zlib.decompress.


Кредит: ответ Яна Вернье , который отмечает вызов zlib.decompressobj.

0 голосов
/ 08 декабря 2017

Просто добавьте заголовки 'Accept-Encoding': 'identity'

import requests

requests.get('http://gett.bike/', headers={'Accept-Encoding': 'identity'})

https://github.com/requests/requests/issues/3849

0 голосов
/ 18 ноября 2010

Как ни странно, у меня была эта ошибка при попытке работать с API переполнения стека с помощью Python.

Мне удалось заставить его работать с объектом GzipFile из каталога gzip, примерно так:

import gzip

gzip_file = gzip.GzipFile(fileobj=open('abc.gz', 'rb'))

file_contents = gzip_file.read()
...