Wie Umlaute statt "komische Zeichen" 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.
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Mittwoch 17. September 2008, 21:17

snafu hat geschrieben:Du meinst, ich soll mit lxml parsen (mit html5lib tu ich's ja schon und baue daraus einen lxml-Baum)? Das Problem ist, dass lxml wohl nicht so fehlertolerant ist. Zumindest bekomme bei dessen Parser nichts brauchbares zurück. :(
Und wie sieht das mit html5lib aus?
My god, it's full of CARs! | Leonidasvoice vs Modvoice
lunar

Mittwoch 17. September 2008, 21:47

snafu hat geschrieben:
Leonidas hat geschrieben:Und wozu das ganze? html5lib und lxml.html existieren.
Du meinst, ich soll mit lxml parsen (mit html5lib tu ich's ja schon und baue daraus einen lxml-Baum)? Das Problem ist, dass lxml wohl nicht so fehlertolerant ist. Zumindest bekomme bei dessen Parser nichts brauchbares zurück. :(
Ist myspace wirklich so kaputt oder hast du nur einfach nicht mit lxml.html geparst (sondern mit lxml.etree)?
BlackJack

Mittwoch 17. September 2008, 22:03

@Hyperion: Du hast da im Endeffekt eine Unicode-Zeichenkette stehen, die Du eben *nicht* explizit kodierst, sondern das Python überlässt. Und wenn da was ausserhalb von ASCII enthalten ist, dann kann's krachen.

Nochmal langsam ``u'%s'.encode('iso-8859-1') % get_moods().decode("iso-8859-1")`` Schritt für Schritt. Der Ausdruck vor dem ``%`` wird zu '%s', das hatten wir ja schon. Gehen wir mal davon aus `get_moods()` gibt 'mööp' als 'iso-8859-1' kodiert zurück, dann wird daraus u'm\xf6\xf6p'. Im nächsten Schritt wird also ``'%s' % u'm\xf6\xf6p'`` ausgwertet. Bei solchen Operationen mit Zeichenketten und Unicode-Objekten wird immer die Zeichenkette implizit zu Unicode umgewandelt (mit ASCII als angenommene Kodierung, aber das ist hier ja kein Problem). Das ist so ähnlich wie Operationen mit ganzen Zahlen und Fliesskommazahlen, wo immer mit Fliesskommazahlen weiter gearbeitet wird. Also läuft's auf ``u'%s' % u'm\xf6\xf6p'`` raus, was auch wieder so eine unnütze Aktion ist, weil's natürlich wieder u'm\xf6\xf6p' als Ergebnis hat. Und da steht jetzt ein ``print`` davor. Damit liefert man sich wieder dem Problem aus, dass das klappen kann, oder auch nicht, je nachdem ob Python die Kodierung von `sys.stdout` richtig raten konnte oder nicht.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7472
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Donnerstag 18. September 2008, 07:45

@BlackJack: Danke für die ausführliche Erklärung :-) Dass bei Operationen mit Zeichenketten und Unicode die Zeichenkette immer intern in Unicode gewandelt wird, war mir wirklich nicht bewusst.

Wie geht man denn nun aber in diesem Falle vor? Also kann ich print irgend wie klar machen, welche Kodierung ein String hat oder wie es etwas korrekt ausgeben soll? In obigen Fall will es ja offensichtlich den ByteString als ASCII ausgeben, was ja das Problem darstellt.
BlackJack

Donnerstag 18. September 2008, 08:14

Naja, entweder man kodiert das Unicode-Objekt direkt beim ``print`` in Bytes, oder man "wrappt" die Ausgabe `sys.stdout` mit einem entsprechenden Objekt aus dem `encodings`-Modul und benutzt dort dann die `write()`-Methode.

Welche Kodierung das Programm, das an `sys.stdout` auf Bytes lauscht, erwartet, kann man nur raten und man sollte IMHO immer die Möglichkeit bieten den Anwender des Programms entscheiden zu lassen.
Benutzeravatar
snafu
User
Beiträge: 5440
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Donnerstag 18. September 2008, 10:29

Hab's hinbekommen: _parser() sieht jetzt so aus:

Code: Alles auswählen

def _parse(self, url):
    return lxml.html.soupparser.parse(self._browser.open(url))
Das liefert mir die Umlaute wie gewünscht zurück und kann mit der bisherigen Syntax weiterverarbeitet werden. :)
Antworten