2010-11-17 15 views
13

Estoy jugando con la API Stack Overflow usando Python. Estoy intentando descifrar las respuestas gzip que da la API.¿Cómo puedo crear una instancia de GzipFile a partir del "objeto similar a un archivo" que devuelve urllib.urlopen()?

import urllib, gzip 

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

Según the urllib2 documentation, urlopen “devuelve un objeto de tipo fichero”.

Sin embargo, cuando corro read() en el objeto GzipFile He creado a usarlo, me sale este error:

AttributeError: addinfourl instance has no attribute 'tell' 

Por lo que yo puedo decir, éste es el del objeto devuelto por urlopen.

no parece tener buscan tampoco, ya que me da un error cuando hago esto:

url.read() 
url.seek(0) 

¿Qué es exactamente este objeto, y cómo puedo crear una instancia GzipFile funcionamiento de ella?

+1

'Content-Encoding: gzip' debe ser manejado por la biblioteca http, pero desafortunadamente no lo es. Este es [problema 9500] (http://bugs.python.org/issue9500) en la base de datos de errores de Python, para el interesado. –

+0

@Magnus: aplausos, es bueno saber que está al menos en el rastreador de errores. –

Respuesta

10

El urlopen docs enumera los métodos compatibles del objeto que se devuelve. Recomiendo envolver el objeto en otra clase que admita los métodos que gzip espera.

Otra opción: llamar al método de lectura del objeto de respuesta y poner el resultado en un objeto StringIO (que debe admitir todos los métodos que gzip espera). Esto tal vez un poco más caro sin embargo.

E.g.

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) 
+0

Envolverlo en un objeto 'StringIO' pasa ese error, pero todavía obtengo un' IOError: No es un archivo comprimido' –

+1

@ThomasK Funciona encontrar para mí. ¿Estás pasando 'url.read()' al constructor 'StringIO' o simplemente' url'? El último falla. – aaronasterling

+0

Sí, eso fue lo que me equivoqué. Gracias. –

8
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 es para Python2.6 +. Para versiones anteriores de Python, puede usar cStringIO.StringIO.

Cuestiones relacionadas