Datei herunterladen...

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
Benutzeravatar
pixewakb
User
Beiträge: 1411
Registriert: Sonntag 24. April 2011, 19:43

Ich bin etwas ratlos:

Code: Alles auswählen

import urllib.request


def DateiDownload(url):
    dateiname = url.rsplit('/',1)
    dateiname = str(dateiname[1])
    webfile = urllib.request.urlopen(url, 'rb')
    f = open(dateiname, 'wb')
    a = webfile.read()
    f.write(a)
    webfile.close()
    f.close()
    print (dateiname, 'heruntergeladen.',sep=' ')
Das ist alter Code von mir. Das lief schon mal so vor einigen Monaten und zwar ohne Fehlermeldungen - das verwirrt mich nun, denn: Wenn ich nun etwas herunterladen will, gibt es eine Reihe von Fehlermeldungen. Hat jemand eine Idee???
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Vielleicht verrätst Du uns einfach mal, welche Fehler denn kommen ;-)

Ggf. mit der URL, damit man es selber testen kann...
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
pixewakb
User
Beiträge: 1411
Registriert: Sonntag 24. April 2011, 19:43

Mal als Beispiel:

Code: Alles auswählen

import urllib.request

def DateiDownload(url):
    dateiname = url.rsplit('/',1)
    dateiname = str(dateiname[1])
    webfile = urllib.request.urlopen(url, 'rb')
    f = open(dateiname, 'wb')
    a = webfile.read()
    f.write(a)
    webfile.close()
    f.close()
    print (dateiname, 'heruntergeladen.',sep=' ')

url = "http://www.python-forum.de/styles/PyFo_Classic/imageset/site_logo.gif"
DateiDownload(url)
Fehlermeldungen:

Code: Alles auswählen

Traceback (most recent call last):
  File "C:/.../text.py", line 17, in <module>
    DateiDownload(url)
  File "C:/.../text.py", line 7, in DateiDownload
    webfile = urllib.request.urlopen(url, 'rb')
  File "C:\...\Python32\lib\urllib\request.py", line 138, in urlopen
    return opener.open(url, data, timeout)
  File "C:\...\Python32\lib\urllib\request.py", line 367, in open
    req = meth(req)
  File "C:\...\Python32\lib\urllib\request.py", line 1066, in do_request_
    raise TypeError("POST data should be bytes"
TypeError: POST data should be bytes or an iterable of bytes. It cannot be str.
Ich bin aus den Fehlermeldungen nicht schlau geworden. Wie gesagt genau das Skript lief bei mir bereits (sehr gut).
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Die Fehlermeldung sieht mir eindeutig aus. Du verwendest einen String (Unicode), sollst aber encodierte Bytes verwenden. Das hat sich ja gegenüber Python 2.x in Python 3 geändert! Das erklärt auch, wieso das vor einiger Zeit noch bei Dir lief: Du hast damals eine 2er Version benutzt ;-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
pixewakb
User
Beiträge: 1411
Registriert: Sonntag 24. April 2011, 19:43

Hi,

hilfst du mir mal mit dem Code aus?

Dachte an etwas wie:

Code: Alles auswählen

url = bytes(url, encoding="utf8")
Wo muss das mit bytes hin!?

PS Ich nutze seit bestimmt einem Jahr Python 3.2 - das hat sich bei mir nicht geändert. Das lief bei mir vor Monaten in dieser Programmversion rund... Deshalb bin ich da auch etwas verwirrt.

PPS Ich habe für das Modul bislang keine Anleitung gefunden, aus der ich schlau geworden wäre... Gibt es da etwas besseres?
Benutzeravatar
pixewakb
User
Beiträge: 1411
Registriert: Sonntag 24. April 2011, 19:43

Schaul mal in meinen Quellcode:

Code: Alles auswählen

print (dateiname, 'heruntergeladen.',sep=' ')
:lol: Das war Python 3er-Code. Ich weiß, dass das gut lief in dieser (!) Version...

Falls da jemand eine Erklärung parat hat, wäre ich auch da für eine Hilfe/Erklärung dankbar. Ich bin mehr sehr sicher, dass ich an Python seit mehreren Monaten nichts geändert habe (kein Update oder Upgrade!).
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Dann hat sich eben etwas im 3er Zweig verändert! Evtl. steht das im Zusammenhang zum WSGI-Problem. In Python 3 setzt die Sprache ja konsequent auf Unicode-Strings, für (Web-)Protokolle braucht es aber Bytes. Da man nicht von einem Defaultencoding ausgehen kann, ist es hier sicherlich sinnvoller, direkt Bytes zu verlangen. Evtl. gab es da eben im `urllib`-Modul eine semantische Änderung.

Wenn die Umwandlung in Bytes so klappt in Python 3 (meine Kenntnisse sind da noch zu gering, da ich bisher eher Python 2 verwende), dann hast Du die Lösung doch schon. Da kapiere ich Deine Nachfrage nicht - der "bytestring" muss eben als Parameter an `urlopen` übergeben werden :K
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
pixewakb
User
Beiträge: 1411
Registriert: Sonntag 24. April 2011, 19:43

Ok. Ich acker mich da noch mal durch:

http://docs.python.org/release/3.2/libr ... quest.html

Auch die Umwandlung nach bytes läuft (so) nicht. Ich habe jetzt schon mal Umwandlung von url und von dateiname versucht.

Ich nutze "Python 3.2.1". In der Anleitung lese ich (http://docs.python.org/release/3.2/libr ... quest.html):
urllib.request.urlopen(url, data=None[, timeout], *, cafile=None, capath=None)
Open the URL url, which can be either a string or a Request object.
Ehrlich gesagt raffe ich die Anleitung zum Modul nicht ganz - möglicherweise bin ich da aber auch zu doof. Ich werde mir das bei Gelegenheit noch mal ansehen; dir aber vielen Dank für die Bemühungen!
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Also laut Anleitung soll man doch einen String übergeben. Aber: Was soll das "rb" da sein? Das sieht ja nach einem File-Parameter aus - so etwas gibt es da laut Doku aber nicht! Lass das doch mal weg...
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
pixewakb
User
Beiträge: 1411
Registriert: Sonntag 24. April 2011, 19:43

Danke :!: - läuft. :P

(Muss ich mir noch mal einen Tag ansehen...)
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

pixewakb hat geschrieben:Danke :!: - läuft. :P

(Muss ich mir noch mal einen Tag ansehen...)
Aber das kann ja dann nicht vorher geklappt haben - da musst Du doch etwas dran geändert haben! Diesen Parameter konnte ich auch nicht in der 2.xer Linie finden...
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Hallo,

mit `urllib.urlretrieve` geht das alles etwas einfacher. Dann kann man auch nicht das with-Statement bei den open-Anweisungen vergessen ;-)

Sebastian
Das Leben ist wie ein Tennisball.
Antworten