2009-12-01 2 views
12

Ich bin perplex darüber, warum ich nicht den gesamten Inhalt einiger JSON-Antworten von FriendFeed mit urllib2 herunterladen kann.urllib2 ruft nicht die gesamte HTTP-Antwort ab

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

Wie kann ich die vollständige Antwort mit Urllib2 abrufen?

+1

der Website gebrochen. Probieren Sie es in einem Browser aus. –

+0

Ich bekomme die volle 165K der Antwort, wenn ich diese URL mit Firefox 3.0 auf Ubuntu 9.04 treffe. Das abgerufene JSON-Dokument ist in meinem Browser wohlgeformt. – gotgenes

+3

Ja, die Website ist defekt. Aber das ist sicherlich ein Fehler in "urllib" und "urllib2", da andere Tools (curl, wget) unvollständige Antworten melden. Es wäre schön zu wissen, was in Python-Bibliotheken nicht stimmt. –

Antwort

18

Der beste Weg, alle Daten zu erhalten:

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 

Die Grund ist, dass .read() nicht die gesamte Antwort zurückgibt, angesichts der Art der Sockets. Ich dachte, das wurde in der Dokumentation diskutiert (vielleicht urllib), aber ich kann es nicht finden.

+2

Ich konnte dieses Beispiel nicht mit der Beispiel-URL in der Frage, http://friendfeed.com/api/room/the-life-scientists/profile?format=json angegebenen arbeiten. Die Antwort ist noch unvollständig. Wie ich John Weldon bereits erwähnte, wiederholen Aufrufe von 'read()' nur leere Strings und 'read()' scheint erschöpfend. – gotgenes

+0

Ich bekomme nur 51,21 KB (52441 Bytes) in meinem Browser. Die Seite ist kaputt. –

+0

Funktioniert auch nicht für http://www.nylonmag.com/modules/magsection/article/uploaded_images/5463_head_minnie%20big.jpg, obwohl wget die ganze Seite zurückgibt und Firefox das jpg anzeigen kann. – dfrankow

2

Halten stream.read() aufrufen, bis es fertig ist ...

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

'read()' ist erschöpfend. Wiederholte Aufrufe geben eine leere Zeichenfolge zurück – gotgenes

+0

Ja, und eine leere Zeichenfolge gibt false zurück ... –

0
readlines() 

funktioniert auch

+1

Es ist nicht für mich. 'Data = '' .join (stream.readlines()); print len ​​(data); print (data [-40:]) 'liefert identische Ergebnisse. – gotgenes

+0

stream.readlines() gibt eine Liste aller Zeilen zurück. Aber ich habe gerade festgestellt, dass Sie das Modul urllib2 verwenden. Meine Antwort basiert auf dem Modul urllib Ich benutze seit längerem und ich habe nur die stream.readlines() aus dem urllib modu überprüft le und es funktioniert einwandfrei – inspectorG4dget

4

Verwenden Sie tcpdump (oder etwas Ähnliches), um die tatsächlichen Netzwerkinteraktionen zu überwachen - dann können Sie analysieren, warum die Site für einige Clientbibliotheken unterbrochen ist. Stellen Sie sicher, dass Sie von Skripts für den Test mehrmals wiederholen, so können Sie sehen, ob das Problem konsistent ist:

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 

Die konsequent für mich der Baustelle arbeiten, so kann ich keine Beispiele finden Ausfälle geben :)

Verwandte Themen