urllib2 no recupera la respuesta HTTP completa
Pregunta
Estoy perplejo por qué no puedo descargar todo el contenido de algunas respuestas JSON de FriendFeed utilizando urllib2 .
>>> 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?
Solución
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
La razón es que .read ()
no garantiza que devuelva la respuesta completa, dada la naturaleza de los sockets. Pensé que esto se discutió en la documentación (tal vez urllib
) pero no puedo encontrarlo.
Otros consejos
Use tcpdump (o algo así) para monitorear las interacciones reales de la red, luego puede analizar por qué el sitio está roto para algunas bibliotecas de clientes. Asegúrese de repetir varias veces mediante 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
El sitio funciona constantemente para mí, así que no puedo dar ejemplos de fallas de búsqueda :)
Sigue llamando a stream.read () hasta que termine ...
while data = stream.read() :
... do stuff with data
readlines()
también funciona