Уведомления

Группа в Telegram: @pythonsu

#1 Апрель 4, 2011 18:53:54

Игнат
От:
Зарегистрирован: 2010-10-02
Сообщения: 224
Репутация: +  0  -
Профиль   Отправить e-mail  

urllib и gzip

интересно, а может ли urllib скачивать ответ сервера в gzip и разжимать его?
или, т.к. он не посылает хидер - Accept-Encoding: gzip,deflate - сервер отдает ему ответ несжатым

но можно ли научить urllib принимать gzip?



Офлайн

#2 Апрель 4, 2011 20:46:01

zheromo
От:
Зарегистрирован: 2010-10-02
Сообщения: 356
Репутация: +  2  -
Профиль   Отправить e-mail  

urllib и gzip

Игнат
т.к. он не посылает хидер - Accept-Encoding: gzip,deflate - сервер отдает ему ответ несжатым
Теоретически да, но это не всегда так, не все сервера следуют стандарту - некоторые отдают gzip всегда.
Игнат
но можно ли научить urllib принимать gzip?
Вот например: http://diveintopython.org/http_web_services/gzip_compression.html



Офлайн

#3 Апрель 6, 2011 13:00:32

Игнат
От:
Зарегистрирован: 2010-10-02
Сообщения: 224
Репутация: +  0  -
Профиль   Отправить e-mail  

urllib и gzip

спасибо
написал такой пример:

import urllib.request as req
import http.client
import io
from gzip import GzipFile

http.client.HTTPConnection.debuglevel = 1

request = req.Request('http://www.thedowntown.ru')
request.add_header('Accept-encoding', 'gzip')

opener = req.build_opener()
f = opener.open(request)

data = f.read().decode('utf-8', 'ignore')
compressedstream = io.StringIO(data)

gzipper = GzipFile(fileobj=compressedstream)
data = gzipper.read()
но получаю эксепшн:
send: b'GET / HTTP/1.1\r\nHost: www.thedowntown.ru\r\nUser-Agent: Python-urllib/3.2\r\nConnection: close\r\nAccept-Encoding: gzip\r\n\r\n'
reply: 'HTTP/1.1 200 OK\r\n'
header: Server header: Date header: Content-Type header: Transfer-Encoding header: Connection header: X-Powered-By header: Expires header: Last-Modified header: Cache-Control header: Accept-Encoding header: Pragma header: Set-Cookie header: Content-Encoding header: Vary ENCODING: gzip


Traceback (most recent call last):
File "/home/python3/gzip_test.py", line 21, in <module>
data = gzipper.read()
File "/usr/local/lib/python3.2/gzip.py", line 331, in read
self._read(readsize)
File "/usr/local/lib/python3.2/gzip.py", line 385, in _read
self._read_gzip_header()
File "/usr/local/lib/python3.2/gzip.py", line 257, in _read_gzip_header
magic = self.fileobj.read(2)
File "/usr/local/lib/python3.2/gzip.py", line 70, in read
self.file.read(size-self._length+read)
TypeError: can't concat bytes to str
в чем может быть причина?

ещё кстати, если качать http://www.google.ru - то он не отдает в gzip, а браузеру отдает



Офлайн

#4 Апрель 6, 2011 13:19:17

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

urllib и gzip

Игнат, да научитесь же наконец работе с байтами и строками!
Получаете HTTPResponse, который io.RawIOBase — так что вам ещё нужно? Какого чорта тянете его в строку через urf-8, потом StringIO? Чтобы получить TypeError в итоге?
Нет, вы не перестаёте меня восхищать!



Офлайн

#5 Апрель 6, 2011 13:42:19

Игнат
От:
Зарегистрирован: 2010-10-02
Сообщения: 224
Репутация: +  0  -
Профиль   Отправить e-mail  

urllib и gzip

где RawIOBase? (даже если бы я знал что это такое)

data = f.read()#.decode('utf-8', 'ignore')
print(type(data)) --> <class 'bytes'>
и этот класс bytes не принимает ни io.StringIO(data), ни GzipFile(fileobj=data)

вам возможно это кажется очевидным и простым, но я лично нихрена не понимаю
и не понимаю даже что надо изучить и гуглить, чтобы это понять

и даже если сделать так:
print(http.client.HTTPResponse)
print(type(http.client.HTTPResponse))
мы получим
<class 'http.client.HTTPResponse'>
<class 'abc.ABCMeta'>
АБЭЦЭ



Офлайн

#6 Апрель 6, 2011 14:14:31

Игнат
От:
Зарегистрирован: 2010-10-02
Сообщения: 224
Репутация: +  0  -
Профиль   Отправить e-mail  

urllib и gzip

заработало, но при помощи zlib
да и код с zlib куда приятнее и понятнее

выложу на всякий случай:

import urllib.request as req
import http.client
import zlib
#http.client.HTTPConnection.debuglevel = 1

def test(gzip=False):

request = req.Request('http://www.thedowntown.ru')
if gzip:
request.add_header('Accept-encoding', 'gzip, deflate')

opener = req.build_opener()
f = opener.open(request)

isGzip = f.headers.get('Content-Encoding')
data_src = f.read()

if isGzip == 'gzip':
print('is GZIP!')
data = zlib.decompress(data_src, 16+zlib.MAX_WBITS)
else:
print('its NOT GZIP!')
data = data_src

data = data.decode('utf-8', 'ignore')
print('downloaded: %d bytes' % len(data_src))
print('decompressed: %d bytes' % len(data))
print('-'*40)

test() # without gzip
test(True) #with gzip
получаем
its NOT GZIP!
downloaded: 13133 bytes
decompressed: 10366 bytes
----------------------------------------
is GZIP!
downloaded: 4731 bytes
decompressed: 10366 bytes
----------------------------------------
но все же непонятно, почему гугл не возвращает гзип скрипту



Отредактировано (Апрель 6, 2011 14:15:34)

Офлайн

#7 Апрель 6, 2011 15:59:31

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

urllib и gzip

print(http.client.HTTPResponse.__mro__)

f = opener.open(request)

gzipper = GzipFile(fileobj=f)
data = gzipper.read()



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version