utf-8 in einer URL

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: 1413
Registriert: Sonntag 24. April 2011, 19:43

Ich habe folgendes Beispielskript (das eigentliche Skript ist deutlich größer), das HTML-Seiten im Netz aufruft, auswertet und ggf. Daten ausliest. Seit heute habe ich eine Adresse drin, die ein Sonderzeichen enthält. Ich habe das mal auf eine Fake-Adresse zusammengekürzt.

Code: Alles auswählen

import urllib.request

url = "http://www.ó.de"  # Fake-Adresse
html = urllib.request.urlopen(url).read()
print(str(html)[:30])
Ich erhalte dann folgende Fehlermeldung:

Code: Alles auswählen

Traceback (most recent call last):
  File "C:/Users/[...]/Desktop/skript.py", line 8, in <module>
    html = urllib.request.urlopen(url).read()
  File "C:\Python34\lib\urllib\request.py", line 153, in urlopen
    return opener.open(url, data, timeout)
  File "C:\Python34\lib\urllib\request.py", line 455, in open
    response = self._open(req, data)
  File "C:\Python34\lib\urllib\request.py", line 473, in _open
    '_open', req)
  File "C:\Python34\lib\urllib\request.py", line 433, in _call_chain
    result = func(*args)
  File "C:\Python34\lib\urllib\request.py", line 1261, in http_open
    return self.do_open(http.client.HTTPConnection, req)
  File "C:\Python34\lib\urllib\request.py", line 1235, in do_open
    h.request(req.get_method(), req.selector, req.data, headers)
  File "C:\Python34\lib\http\client.py", line 1066, in request
    self._send_request(method, url, body, headers)
  File "C:\Python34\lib\http\client.py", line 1094, in _send_request
    self.putrequest(method, url, **skips)
  File "C:\Python34\lib\http\client.py", line 958, in putrequest
    self._output(request.encode('ascii'))
UnicodeEncodeError: 'ascii' codec can't encode character '\xf3' in position 20: ordinal not in range(128)
Im Kern geht es darum, dass hier unterschiedliche encodings genutzt werden, da die Seite im Netz liegt und der Fehler im Modul liegt, habe ich darauf m. E. keinen Einfluss.

Kann ich in meinem Skript etwas ändern, dass der Fehler nicht mehr auftritt.
Zuletzt geändert von pixewakb am Samstag 16. Mai 2015, 22:47, insgesamt 1-mal geändert.
Benutzeravatar
pixewakb
User
Beiträge: 1413
Registriert: Sonntag 24. April 2011, 19:43

Ich bin auch noch im Netz fündig geworden und komme gerade weiter.

Als Workaround funktioniert das:

Code: Alles auswählen

url.replace("ó","%C3%B3")
U. a. hier wird der Fehler beschrieben und es werden Lösungshinweise gegeben.

Ich habe jetzt folgende für mich lauffähige Version gefunden:

Code: Alles auswählen

import urllib.request
from urllib import parse

url = "http://www.ó.de"  # Fake-Adresse

scheme, netloc, path, query, fragment = parse.urlsplit(link)
path = parse.quote(path)
link = parse.urlunsplit((scheme, netloc, path, query, fragment))

html = urllib.request.urlopen(link).read()

print(str(html)[:30])
Das Problem ist damit gelöst.
BlackJack

@pixewakb: Schönes Beispiel für Probleme die auf einen Stellvertreter ”reduziert” wird der das Problem dann gar nicht aufweist, oder ein anderes Problem. An der Stelle wo Dein 'ó' nämlich steht würde Deine Lösung nicht funktionieren, *und* Du hättest statt des `replace()` auch einfach UTF-8 kodieren können, was vielleicht a) deutlicher macht was da passiert und b) nicht nur mit 'ó' funktioniert.
Benutzeravatar
/me
User
Beiträge: 3561
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Eine Adresse wie http://www.ó.de muss eigentlich punicode-kodiert werden.

Code: Alles auswählen

>>> import codecs
>>> url = 'http://www.ó.de'
>>> code = codecs.encode(url, 'punycode')
>>> print(code)
b'http://www..de-vob'
>>> print(codecs.decode(code, 'punycode'))
http://www.ó.de
Benutzeravatar
pixewakb
User
Beiträge: 1413
Registriert: Sonntag 24. April 2011, 19:43

Sagen wir mal, ich parse Webseiten. Kann ich jede Webseite damit parsen bzw. konvertieren oder würdest du das nicht machen!? Ich habe heute durch Zufall ein Ergebnis ausgespuckt bekommen, wo ich anscheinend auch ein Sonderzeichen drin hatte, dass dann durch eine Raute mit Fragezeichen ersetzt wurde.

Sorry, das ich den alten Thread noch mal aufwärme.
Benutzeravatar
/me
User
Beiträge: 3561
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

pixewakb hat geschrieben:Sorry, das ich den alten Thread noch mal aufwärme.
Vor allem hast du ein anderes Thema. Hier ging es um Codierung von Sonderzeichen in der URL, bei dir geht es um die Codierung des Inhalts der abgerufenen Webseite.

Mit welcher Python-Version und welcher Bibliothek rufst du denn mit welchem Code die Daten ab?
Benutzeravatar
pixewakb
User
Beiträge: 1413
Registriert: Sonntag 24. April 2011, 19:43

Ui, das kann ich nicht (mehr) direkt beantworten. Verstehe aber jetzt das Problem wieder.

Ich nutze Python 3.4.0 und das Request-Modul. Momentan ist die Zahl der Tools, die verschiedenste Aufgaben - i. d. R. Daten abrufen und für die weitere Verarbeitung bereitstellen - sehr umfangreich. Von den Programmen sehe ich meistens nur noch die Ergebnisse, ohne Vermerk, welches Tool das erledigt. Ich räume von Zeit zu Zeit auf, momentan hat sich aber ein gewisser Arbeitsrückstau eingestellt.
Benutzeravatar
pixewakb
User
Beiträge: 1413
Registriert: Sonntag 24. April 2011, 19:43

Problem hat sich erledigt! Danke!

Zum Hintergrund: Ich erzeuge schon mal HTML-Dateien, die mir Informationen zusammengestellt präsentieren. Die Dateien sind falsch codiert, was ich ändern kann. Ich denke, dass daher der Fehler kommt. Ich habe das gerade bei einer anderen Datei feststellen müssen.
Antworten