2009-12-01 12 views
12

Estoy perplejo de por qué no puedo descargar todo el contenido de algunas respuestas JSON desde FriendFeed usando urllib2.urllib2 no recupera toda la respuesta HTTP

>>> import urllib2 
>>> stream = urllib2.urlopen('http://friendfeed.com/api/room/the-life-scientists/profile?format=json') 
>>> stream.headers['content-length'] 
'168928' 
>>> data = stream.read() 
>>> len(data) 
61058 
>>> # We can see here that I did not retrieve the full JSON 
... # given that the stream doesn't end with a closing } 
... 
>>> data[-40:] 
'ce2-003048343a40","name":"Vincent Racani' 

¿Cómo puedo recuperar la respuesta completa con urllib2?

+1

sitio de roto. Pruebe en un navegador. –

+0

Obtengo los 165 KB completos de respuesta cuando toco esa URL con Firefox 3.0 en Ubuntu 9.04. El documento JSON recuperado está bien formado en mi navegador. – gotgenes

+3

Sí, el sitio está roto. Pero esto es ciertamente un error tanto en 'urllib' como' urllib2', ya que otras herramientas (curl, wget) informan una respuesta incompleta. Sería bueno saber qué está mal en las bibliotecas de Python. –

Respuesta

18

La mejor manera de obtener todos los datos:

fp = urllib2.urlopen("http://www.example.com/index.cfm") 

response = "" 
while 1: 
    data = fp.read() 
    if not data:   # This might need to be if data == "": -- can't remember 
     break 
    response += data 

print response 

El El motivo es que no se garantiza que .read() devuelva toda la respuesta, dada la naturaleza de los sockets. Pensé que esto se discutió en la documentación (tal vez urllib) pero no puedo encontrarlo.

+2

No pude obtener este ejemplo para trabajar con la URL de ejemplo que figura en la pregunta, http://friendfeed.com/api/room/the-life-scientists/profile?format=json. La respuesta aún está incompleta. Como mencioné a John Weldon, las llamadas repetidas a 'read()' solo devuelven cadenas vacías, y 'read()' parece exhaustivo. – gotgenes

+0

Solo obtengo 51.21 KB (52441 bytes) en mi navegador. El sitio está roto. –

+0

Tampoco funciona para http://www.nylonmag.com/modules/magsection/article/uploaded_images/5463_head_minnie%20big.jpg, aunque wget devuelve la página completa, y Firefox puede mostrar el jpg. – dfrankow

2

seguir llamando stream.read() hasta que se hace ...

while data = stream.read() : 
    ... do stuff with data 
+2

'read()' es exhaustivo. Repetir llamadas devuelve una cadena vacía. – gotgenes

+0

sí, y una cadena vacía devuelve falso ... –

0
readlines() 

también trabaja

+1

No es para mí. 'Data = '' .join (stream.readlines()); print len ​​(data); print (datos [-40:]) 'da resultados idénticos. – gotgenes

+0

stream.readlines() devuelve una lista de todas las líneas. Pero también me di cuenta de que está utilizando el módulo urllib2. Mi respuesta se basó en el módulo urllib que He estado usando durante más tiempo y he comprobado dos veces la secuencia.readlines() desde el modu urllib y funciona correctamente – inspectorG4dget

4

Use tcpdump (o algo así) para supervisar las interacciones de red reales; a continuación, puede analizar por qué el sitio está roto para algunas bibliotecas de clientes. Asegúrese de que se repita varias veces por secuencias de comandos de la prueba, para que pueda ver si el problema es consistente:

import urllib2 
url = 'http://friendfeed.com/api/room/friendfeed-feedback/profile?format=json' 
stream = urllib2.urlopen(url) 
expected = int(stream.headers['content-length']) 
data = stream.read() 
datalen = len(data) 
print expected, datalen, expected == datalen 

del sitio de trabajo constante para mí, así que no puedo dar ejemplos de la búsqueda de fallos :)

Cuestiones relacionadas