Urllib's Urlopen Breaking en algunos sitios (por ejemplo, la API de StackApps): devuelve los resultados de la basura

StackOverflow https://stackoverflow.com/questions/3028426

Pregunta

Estoy usando urllib2's urlopen Funciona para intentar obtener un resultado JSON de la API StackOverflow.

El código que estoy usando:

>>> import urllib2
>>> conn = urllib2.urlopen("http://api.stackoverflow.com/0.8/users/")
>>> conn.readline()

El resultado que estoy obteniendo:

'\x1f\x8b\x08\x00\x00\x00\x00\x00\x04\x00\xed\xbd\x07`\x1cI\x96%&/m\xca{\x7fJ\...

Soy bastante nuevo en Urllib, pero este no parece el resultado que debería recibir. Lo he probado en otros lugares y obtengo lo que espero (lo mismo que visitar la dirección con un navegador me da: un objeto JSON).

Usando urlopen en otros sitios (por ejemplo "http://google.com") funciona bien y me da HTML real. También he intentado usar urllib y da el mismo resultado.

Estoy bastante atascado, sin saber dónde buscar para resolver este problema. ¿Algunas ideas?

¿Fue útil?

Solución

Eso casi se parece a algo que estarías alimentando para encurtir. Tal vez algo en la cadena del agente de usuario o acepte el encabezado que Urllib2 está enviando está causando que StackOverflow envíe algo más que JSON.

Un revelador es mirar conn.headers.headers Para ver qué dice el encabezado de tipo de contenido.

Y esta pregunta, Resultado del formato de cadena impar de la llamada API, puede tener su respuesta. Básicamente, es posible que deba ejecutar su resultado a través de un descompresor GZIP.

Verificación doble con este código:

>>> req = urllib2.Request("http://api.stackoverflow.com/0.8/users/",
                          headers={'Accept-Encoding': 'gzip, identity'})
>>> conn = urllib2.urlopen(req)
>>> val = conn.read()
>>> conn.close()
>>> val[0:25]
'\x1f\x8b\x08\x00\x00\x00\x00\x00\x04\x00\xed\xbd\x07`\x1cI\x96%&/m\xca{\x7fJ'

Sí, definitivamente está recuperando los datos codificados por GZIP.

Dado que parece obtener diferentes resultados en diferentes máquinas con la misma versión de Python, y en general parece que la API de Urllib2 requeriría que haga algo especial para solicitar datos codificados por GZIP, supongo que tiene un proxy transparente allí en algún lugar.

Vi una presentación del EFF en Codecon en 2009. Estaban haciendo pruebas de conectividad de extremo a extremo para descubrir trucos de ISP sucios de varios tipos. Una de las cosas que descubrieron al hacer esta prueba es que un sorprendente número de enrutadores NAT a nivel de consumidor agregan encabezados HTTP aleatorios o proxy transparente. Es posible que tenga un equipo en su red que está agregando o modificando el Accept-Encoding encabezado para que su conexión parezca más rápida.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top