Как я могу создать экземпляр GzipFile из «файлового объекта», который возвращает urllib.urlopen ()? - PullRequest
14 голосов
/ 17 ноября 2010

Я играю с API переполнения стека, используя Python. Я пытаюсь декодировать сжатые ответы, которые дает API.

import urllib, gzip

url = urllib.urlopen('http://api.stackoverflow.com/1.0/badges/name')
gzip.GzipFile(fileobj=url).read()

Согласно документации urllib2 , urlopen «возвращает объект, похожий на файл».

Однако, когда я запускаю read() на объекте GzipFile, который я создал с его помощью, я получаю эту ошибку:

AttributeError: addinfourl instance has no attribute 'tell'

Насколько я могу судить, это исходит от объекта, возвращаемого urlopen.

Похоже, он тоже не ищет, поскольку я получаю сообщение об ошибке:

url.read()
url.seek(0)

Что это за объект и как мне создать из него функционирующий GzipFile экземпляр?

Ответы [ 2 ]

10 голосов
/ 17 ноября 2010

В urlopen docs перечислены поддерживаемые методы возвращаемого объекта.Я рекомендую обернуть объект в другой класс, который поддерживает методы, ожидаемые gzip.

Другая опция: вызвать метод read объекта ответа и поместить результат в объект StringIO (который долженподдержите все методы, которые ожидает gzip).Это может быть немного дороже, хотя.

Например

import gzip
import json
import StringIO
import urllib

url = urllib.urlopen('http://api.stackoverflow.com/1.0/badges/name')
url_f = StringIO.StringIO(url.read())
g = gzip.GzipFile(fileobj=url_f)
j = json.load(g)
8 голосов
/ 17 ноября 2010
import urllib2
import json
import gzip
import io

url='http://api.stackoverflow.com/1.0/badges/name'
page=urllib2.urlopen(url)
gzip_filehandle=gzip.GzipFile(fileobj=io.BytesIO(page.read()))
json_data=json.loads(gzip_filehandle.read())
print(json_data)

io.BytesIO для Python2.6 +.Для более старых версий Python вы можете использовать cStringIO.StringIO.

...