2009-12-01 15 views
12

Sono perplesso sul motivo per cui non riesco a scaricare l'intero contenuto di alcune risposte JSON da FriendFeed utilizzando urllib2.urllib2 non recupera l'intera risposta 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' 

Come posso recuperare la risposta completa con urllib2?

+1

il sito di rotto. Prova in un browser. –

+0

Ottengo il 165K completo della risposta quando si colpisce quell'URL con Firefox 3.0 su Ubuntu 9.04. Il documento JSON recuperato è ben formato nel mio browser. – gotgenes

+3

Sì, il sito è rotto. Ma questo è certamente un bug sia in 'urllib' che in' urllib2', poiché altri strumenti (curl, wget) riportano una risposta incompleta. Sarebbe bello sapere cosa c'è di sbagliato nelle librerie Python. –

risposta

18

Il modo migliore per ottenere tutti i dati:

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 

Il La ragione è che non è garantito che .read() restituisca l'intera risposta, data la natura dei socket. Ho pensato che questo fosse discusso nella documentazione (forse urllib) ma non riesco a trovarlo.

+2

Non ho potuto ottenere questo esempio per lavorare con l'URL di esempio fornito nella domanda, http://friendfeed.com/api/room/the-life-scientists/profile?format=json. La risposta è ancora incompleta. Come ho detto a John Weldon, ripetete le chiamate a 'read()' restituite solo stringhe vuote, e 'read()' sembra esauriente. – gotgenes

+0

Nel mio browser ottengo solo 51,21 KB (52441 byte). Il sito è rotto –

+0

Inoltre, non funziona per http://www.nylonmag.com/modules/magsection/article/uploaded_images/5463_head_minnie%20big.jpg, sebbene wget restituisca l'intera pagina e Firefox possa visualizzare il jpg. – dfrankow

2

continuare ad invocare stream.read() finché non è finito ...

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

'read()' è completo. Ripeti le chiamate per restituire una stringa vuota – gotgenes

+0

sì, e una stringa vuota restituisce false ... –

0
readlines() 

funziona anche

+1

Non fa per me. 'Data = '' .join (stream.readlines()); print len ​​(data); print (data [-40:]) 'dà risultati identici – gotgenes

+0

stream.readlines() restituisce un elenco di tutte le righe, ma mi sono anche reso conto che stai usando il modulo urllib2 La mia risposta era basata sul modulo urllib che Sto usando più a lungo e ho appena controllato due volte stream.readlines() dal mod di urllib le e funziona correttamente – inspectorG4dget

4

Utilizzare tcpdump (o qualcosa di simile) per monitorare le interazioni di rete effettive - quindi è possibile analizzare il motivo per cui il sito è danneggiato per alcune librerie client. Assicurarsi che si ripete più volte da script del test, in modo da poter vedere se il problema è 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 sito lavora costantemente per me, quindi non posso dare esempi di fallimenti trovare :)

Problemi correlati