urlretrieve - url mit Umlauten

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
JosefK
User
Beiträge: 4
Registriert: Samstag 12. Dezember 2015, 16:30

Hallo,

ich habe ein Problem mit urlretrieve, das ich nicht gelöst bekomme. Ich möchte gerne eine Datei mit urlretrieve herunterladen, die im Namen einen Umlaut enthält. Leider bricht dann das Skript immer mit folgender Fehlermeldung ab.

Code: Alles auswählen

UnicodeEncodeError: 'ascii' codec can't encode character '\xe4' in position 47: ordinal not in range(128)
die Codeziele dazu:

Code: Alles auswählen

urllib.request.urlretrieve(str(parser.piclink), "./"+year+"/"+month+"/" + str(PicOfFolder) + ".jpg")
Muss ich den Link noch irgendwie umcodieren?
BlackJack

@JosefK: Ja musst Du. Versuch's mal mit UTF-8.
JosefK
User
Beiträge: 4
Registriert: Samstag 12. Dezember 2015, 16:30

Ich bin leider voll am verzweifeln. Nichts was ich ausprobiere klappt. Unicode, str, .encode oder .decode. Nichts klappt.

Wie bekomme ich denn einen Sring mit Umlaut in ein UTF-8 Format?

Code: Alles auswählen

#!/usr/bin/env python3.3
# coding: utf8

...

string_something= "http://test/täst.jpg"
# wie konvertieren
urllib.request.urlretrieve( string_something , "./"+year+"/"+month+"/" + str(PicOfFolder) + ".jpg" )		
BlackJack

JosefK: Einfach `encode()` mit der gewünschten Kodierung auf der (Unicode)Zeichenkette aufrufen und Du bekommst ein `bytes`-Objekt.
JosefK
User
Beiträge: 4
Registriert: Samstag 12. Dezember 2015, 16:30

Das habe ich schon versucht, aber ich bekomme immer folgende Fehlermeldung.

Code: Alles auswählen

    urllib.request.urlretrieve(  inputstr, "./"+year+"/"+month+"/" + str(PicOfFolder) + ".jpg" )		
  File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/urllib/request.py", line 179, in urlretrieve
    url_type, path = splittype(url)
  File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/urllib/parse.py", line 852, in splittype
    match = _typeprog.match(url)
TypeError: can't use a string pattern on a bytes-like object
für folgenden code

Code: Alles auswählen

	string_something= "http://test/täst.jpg"
	inputstr = string_something.encode('utf-8', 'replace')
	urllib.request.urlretrieve(  inputstr, "./"+year+"/"+month+"/" + str(PicOfFolder) + ".jpg" )

Deshalb habe ich dann das ganze wieder mit decode('utf-8') umgewandelt und dann bin ich wieder da wo ich am Anfang war :) Ich werd verrückt. Ich verstehe das nicht.
Sirius3
User
Beiträge: 17710
Registriert: Sonntag 21. Oktober 2012, 17:20

@JosefK: URLs dürfen nur bestimmte 7bit-ASCII-Zeichen enthalten. Die anderen Zeichen müssen gequotet werden:

Code: Alles auswählen

url = urllib.request.quote("http://test/täst.jpg", safe=':/')
filename = "./{}/{}/{}.jpg".format(year, month, PicOfFolder)
urllib.request.urlretrieve(url, filename)
BlackJack

An der Stelle sollte man vielleicht auch mal `requests` erwähnen was keine weiteren externen Abhängigkeiten als die Standardbibliothek hat und eine wesentlich freundlichere API bietet weil es sich um solche Sachen intern selber kümmert. Dann muss man sich zwar das kopieren in die lokale Datei selber programmieren, aber das ist weit weniger umständlich als sich um die ganzen URL- und HTTP-Details selber zu kümmern. Ungetestet:

Code: Alles auswählen

import requests

CHUNK_SIZE = 32 * 1024


def main():
    response = requests.get('http://example.org/täst.jpg', stream=True)
    if response.ok:
        with open('something.jpg', 'wb') as image_file:
            image_file.writelines(response.iter_content(CHUNK_SIZE))
 

if __name__ == '__main__':
    main()
JosefK
User
Beiträge: 4
Registriert: Samstag 12. Dezember 2015, 16:30

@Sirius3: Vielen Dank. Das Skript schnurrt jetzt wie ein Kätzchen :)

@BlackJack: Vielen Dank für die Alternative. Das kommt auch die ToDo-Liste!
Antworten