urllib2: bei einem .read den Fortschritt anzeigen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
JonnyGuitar
User
Beiträge: 6
Registriert: Mittwoch 13. Februar 2008, 14:43

Donnerstag 24. April 2008, 09:32

Moin zusammen,

ich habe folgendes Problem, und zwar lade ich mit folgenden Befehlen ein Dokument aus dem Netz auf den Rechner:

Code: Alles auswählen

.
.
req = urllib2.Request(self.server, data, headers)
.
handle = urllib2.urlopen(req)
return = handle.read()
ich weiss, dass ich mit

Code: Alles auswählen

content_len = handle.info()['Content-length']
die Gesamtgrösse des Dokuments herauskriege.
Hat einer eine Idee wie ich während dem .read Statusmeldungen
zurückbekommen könnte um den Fortschritt auszurechnen und in
einer Progressbar darstellen könnte?

Vielen Dank für eure Hilfe.

mfg Jonny
Benutzeravatar
dennda
User
Beiträge: 17
Registriert: Montag 19. November 2007, 22:07

Donnerstag 24. April 2008, 09:58

Du hast die Content-Length und read() aktzeptiert hier ein Argument.
Siehe:
Help on built-in function read:

read(...)
read([size]) -> read at most size bytes, returned as a string.

If the size argument is negative or omitted, read until EOF is reached.
Notice that when in non-blocking mode, less data than what was requested
may be returned, even if no size parameter was given.
Lies einfach in einer Schleife immer einen Happen ein, also eine bestimmte Anzahl Bytes und bei jedem Schritt aktualisierst du deinen Fortschrittsbalken.
Ich hab das selbst mal gemacht, aber ich hab den Code grade nicht hier.

//edit: Übrigens *muss* bei deinem Request die Content-Length nicht mitgegeben werden. Das solltest du noch überprüfen. Der Stream könnte auch 'chunked' kommen o.ä.

grüße
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

Donnerstag 24. April 2008, 10:34

Ich habe mal sowas für FTP gemacht. Das bringt dich hoffentlich auf den richtigen Weg.
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

Donnerstag 24. April 2008, 10:57

Gnah...ich glaube ich bau dafür mal ne Subclass von socket.Socket.

Ich brauch das demnächst nämlich auch :D
JonnyGuitar
User
Beiträge: 6
Registriert: Mittwoch 13. Februar 2008, 14:43

Donnerstag 24. April 2008, 12:28

Erstmal vielen Dank für eure Hilfe.

Jetzt taucht folgendes Problem auf: Ich habe folgende Stelle

Code: Alles auswählen

return = handle.read()
durch

Code: Alles auswählen

while True:
    data = handle.read(8192)
    if not data:
        break
ersetzt. Nur steht in data nichts mehr drin und er springt direkt auf break.
Ersetze ich das Ganze wieder durch den alten Code geht das ganze wieder.

Was mache ich falsch?
BlackJack

Donnerstag 24. April 2008, 12:47

Überleg Dir mal genau was in der Schleife passiert, insbesondere was die Abbruchbedingung ist und welchen Wert `data` nach der Schleife deswegen *immer* haben *muss*. Ein ``print data`` vor dem ``if`` bringt vielleicht etwas Licht in die Sache.
JonnyGuitar
User
Beiträge: 6
Registriert: Mittwoch 13. Februar 2008, 14:43

Montag 28. April 2008, 09:18

Guten Morgen,

nachdem ich jetzt das ganze Wochenende davor gesessen habe und immer noch zu keiner Lösung gekommen bin möchte ich hier nochmal nachfragen. Ich habe mir data ausgeben lassen, dieses ist immer leer. Aber ich lese doch vorher was in diese Variable ein. Vielleicht hat einer noch ein Denkanstoss für mich, habe momentan voll das Brett vorm Kopf.


mfg Jonny
BlackJack

Montag 28. April 2008, 09:25

`data` ist nicht *immer* leer sondern nur nach der Schleife. Das muss es ja aber auch, weil genau dass die Bedingung ist, bei der die Schleife überhaupt abbricht. Denn solange `data` etwas enthält ist der Code in der Schleife.

Du liest zwar etwas in die Variable ein, aber im nächsten Schleifendurchlauf wird der Name wieder an andere Daten gebunden. Hier würdest Du ja auch nicht erwarten, dass "Hallo" ausgegeben wird, nur weil das irgend wann einmal an `text` gebunden war:

Code: Alles auswählen

text = 'Hallo'
text = ''
print text
Antworten