2009-12-01 5 views
12

Je suis perplexe quant à la raison pour laquelle je ne suis pas en mesure de télécharger tout le contenu de certaines réponses JSON à partir de FriendFeed en utilisant urllib2.urllib2 ne récupère pas la réponse HTTP entière

>>> 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' 

Comment puis-je récupérer la réponse complète avec urllib2?

+1

site de cassé. Essayez dans un navigateur. –

+0

Je reçois la réponse 165K complète en tapant cette URL avec Firefox 3.0 sur Ubuntu 9.04. Le document JSON récupéré est bien formé dans mon navigateur. – gotgenes

+3

Oui, le site est cassé. Mais c'est certainement un bug à la fois dans 'urllib' et' urllib2', puisque d'autres outils (curl, wget) signalent une réponse incomplète. Ce serait bien de savoir ce qui ne va pas dans les bibliothèques python. –

Répondre

18

La meilleure façon d'obtenir toutes les données:

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 

Le raison est que .read() n'est pas garanti pour retourner toute la réponse, compte tenu de la nature des douilles. Je pensais que cela a été discuté dans la documentation (peut-être urllib) mais je ne peux pas le trouver.

+2

Je ne pouvais pas obtenir cet exemple pour travailler avec l'exemple d'URL donné dans la question, http://friendfeed.com/api/room/the-life-scientists/profile?format=json. La réponse est encore incomplète. Comme je l'ai mentionné à John Weldon, les appels répétés à 'read()' ne renvoient que des chaînes vides, et 'read()' semble exhaustif. – gotgenes

+0

Je reçois seulement 51.21 KB (52441 octets) dans mon navigateur. Le site est cassé. –

+0

Ne fonctionne pas non plus pour http://www.nylonmag.com/modules/magsection/article/uploaded_images/5463_head_minnie%20big.jpg, bien que wget renvoie la page entière, et Firefox peut afficher le jpg. – dfrankow

2

continuer à appeler stream.read() jusqu'à ce qu'il soit fait ...

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

'read()' est exhaustive. Répétez les appels pour lui renvoyer une chaîne vide – gotgenes

+0

oui, et une chaîne vide renvoie false ... –

0
readlines() 

travaille également

+1

Il n'est pas pour moi. 'Data = '' .join (stream.readlines()); print len ​​(data); print (data [-40:]) 'donne des résultats identiques – gotgenes

+0

stream.readlines() retourne une liste de toutes les lignes, mais je me suis également rendu compte que vous utilisiez le module urllib2. J'utilise depuis plus longtemps et j'ai juste vérifié le stream.readlines() du module urllib le et il fonctionne correctement – inspectorG4dget

4

Utilisez tcpdump (ou quelque chose comme ça) pour surveiller les interactions réseau réelles - alors vous pouvez analyser pourquoi le site est cassé pour certaines bibliothèques client. Assurez-vous de répéter plusieurs fois par script le test, de sorte que vous pouvez voir si le problème est cohérente:

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 

travail de Le site toujours pour moi je ne peux pas donner des exemples d'échecs trouver :)

Questions connexes