Как лучше всего распаковать ответ сервера в формате gzip в Python 3?
-
23-08-2019 - |
Вопрос
Я ожидал, что это сработает:
>>> import urllib.request as r
>>> import zlib
>>> r.urlopen( r.Request("http://google.com/search?q=foo", headers={"User-Agent": "Mozilla/5.0 (X11; U; Linux i686) Gecko/20071127 Firefox/2.0.0.11", "Accept-Encoding": "gzip"}) ).read()
b'af0\r\n\x1f\x8b\x08...(long binary string)'
>>> zlib.decompress(_)
Traceback (most recent call last):
File "<pyshell#87>", line 1, in <module>
zlib.decompress(x)
zlib.error: Error -3 while decompressing data: incorrect header check
Но это не так.Погружение в Python использует StringIO в этом примере, но, похоже, этого нет в Python 3.Как правильно это сделать?
Решение
Он отлично работает с gzip
(gzip и zlib — это одно и то же сжатие, но с разными заголовками/«оберткой».У вашей ошибки эта информация есть в сообщении).
import gzip
import urllib.request
request = urllib.request.Request(
"http://google.com/search?q=foo",
headers={
"Accept-Encoding": "gzip",
"User-Agent": "Mozilla/5.0 (X11; U; Linux i686) Gecko/20071127 Firefox/2.0.0.11",
})
response = urllib.request.urlopen(request)
gzipFile = gzip.GzipFile(fileobj=response)
gzipFile.read()
Другие советы
В Python 3 StringIO
это класс в io
модуль.
Итак, для примера, на который вы ссылаетесь, если вы измените:
import StringIO
compressedstream = StringIO.StringIO(compresseddata)
к:
import io
compressedstream = io.StringIO(compresseddata)
это должно сработать.
Для тех, кто использует Python 3.2 или более позднюю версию, есть еще более простой способ распаковать ответ, чем любой из ответов здесь:
import gzip
import urllib.request
request = urllib.request.Request(
"http://example.com/",
headers={"Accept-Encoding": "gzip"})
response = urllib.request.urlopen(request)
result = gzip.decompress(response.read())
Не связан с StackOverflow