Seite 1 von 1

UnicodeEncodeError

Verfasst: Samstag 18. Juni 2011, 22:02
von nvidia
Hallo ich hab ein Problem,
ich hab folgenden string:
=?ISO-8859-1?Q?TOP_RISIKO-Lebensversicherung_=96_jetzt_g=FCnstig_sichern?=
jage den durch folgende Methode:

Code: Alles auswählen

	def _back2unicode(self, s, default = 'iso-8859-15'):
		for txt, char in email.header.decode_header(s):
			try:
				s = unicode(txt, char or 'ascii', 'strict')
			except:
				s = txt.decode(default, 'ignore')
			finally:
				return u'{0}'.format(s)
Also Ergebnis erhalte ich:
u'Top Risiko-Lebensversicherung \x96 jetzt g\xfcnstig sichern'
und wenn ich den jetzt über print ausgebe krieg ich den Fehler:
UnicodeEncodeError: 'charmap' codec can't encode character u'\x96' in position 30: character maps to <undefined>
in einer internen Methode >> return codecs.charmap_encode(input,errors,encoding_map)
Woher kommt der Fehler? Wie behebe ich ihn?

Re: UnicodeEncodeError

Verfasst: Samstag 18. Juni 2011, 22:11
von Hyperion
nvidia hat geschrieben: ich hab folgenden string:
=?ISO-8859-1?Q?TOP_RISIKO-Lebensversicherung_=96_jetzt_g=FCnstig_sichern?=
Das ist doch keine `repr`-Ausgabe!?! Woher kommt denn der String? Wie kommst Du auf diese Darstellung?

Re: UnicodeEncodeError

Verfasst: Samstag 18. Juni 2011, 22:18
von nvidia
Das ist ein Q-encoded string für den versand von emails.
Und diese Methode soll sie wieder umwandeln.
Den string hab ich von einem realen email-betreff.
Was ist 'repr'?
Also bei den anderen Emails in meinem Postfach lief das normal auch in der Console werden üäös richtig angezeigt.
Ich weiß nur nicht genau, wieso das hier nicht klappt.
// Also ich das nochmal schritt per schritt mit der hand durchgeganngen
header.decode liefert
schon den string den man am Ende sieht.
Nach unicode() sollte jetzt die ganzen \x-zeichen verschwinden.
Das tun sie aber nicht => a) die Methode funktioniert nicht richtig b) der String war von anfang an fehlerhaft

Re: UnicodeEncodeError

Verfasst: Samstag 18. Juni 2011, 23:44
von nvidia
pfff hab endlich die Lösung.
Man kann das Zeichen nicht anzeigen, sie existieren aber.
Deswegen wirft unicode keine Fehlermeldung, aber print.
aus wiki:
Den Positionen 00–1F und 7F–9F sind in ISO/IEC 8859 und damit ISO/IEC 8859-1 keine Zeichen zugewiesen. ISO-8859-1 jedoch besetzt alle diese Stellen mit nicht darstellbaren Steuerzeichen.

Re: UnicodeEncodeError

Verfasst: Sonntag 19. Juni 2011, 08:38
von Hyperion
Da Deine for-Schleife ja eh nach der ersten Zeile abbricht, wieso machst Du das nicht einfach so und nimmst direkt das erste Tupel?

Code: Alles auswählen

In [29]: msg, encoding = email.header.decode_header(qenc)[0]

In [30]: msg.decode(encoding)
Out[30]: u'TOP RISIKO-Lebensversicherung \x96 jetzt g\xfcnstig sichern'

In [31]: print msg.decode(encoding)
TOP RISIKO-Lebensversicherung  jetzt günstig sichern
Dein finally ist auf jeden Fall komplizierter als notwendig, da Du `s` einfach auch so zurückgeben könntest - das ist ja da schon ein unicode-Objekt ;-)

Sollte es nicht immer ein Encoding geben, so hast Du ja ein default-Encoding - wozu die Verrenkung mit "ascii"?

Desweiteren sieht der Code inkonsistent aus - wieso nutzt Du nicht beide Male die `str.decode`-Methode?

Es ist idR. unschön, wenn man an einen Namen unterschiedliche Typen bindet, zudem ist `s` recht kryptisch. Wie wäre es mit `message` oder `msg` und dann `decoded_message` oder `dec_msg`? Oder Du nimmst direkteren Bezug und nennst es sogar `qencoded` und `qdecoded`; je nach Gusto noch mit `_message` oder `_msg` Suffix.

Re: UnicodeEncodeError

Verfasst: Sonntag 19. Juni 2011, 12:54
von nvidia
okay danke, jetzt sieht das um einiges lesbarer aus.
Wie hast du das geschafft, dass das \x96 verschwindet in der letzten Ausgabe?
Ich krieg da immer noch den Error

Re: UnicodeEncodeError

Verfasst: Sonntag 19. Juni 2011, 17:19
von nomnom
nvidia hat geschrieben:okay danke, jetzt sieht das um einiges lesbarer aus.
Wie hast du das geschafft, dass das \x96 verschwindet in der letzten Ausgabe?
Ich krieg da immer noch den Error
Du verwendest vermutlich Windows und die Windows Shell und die benutzt dieses cp850-Encoding und das wirft da immer diese Fehler bei nicht-Unicode-Strings. Wie man das beheben kann weiß ich auch nicht.

Re: UnicodeEncodeError

Verfasst: Sonntag 19. Juni 2011, 18:22
von Hyperion
nomnom hat geschrieben: Du verwendest vermutlich Windows und die Windows Shell und die benutzt dieses cp850-Encoding und das wirft da immer diese Fehler bei nicht-Unicode-Strings. Wie man das beheben kann weiß ich auch nicht.
Nein, bitte nicht Dinge vermischen! Auf eine Shell werden immer kodierte Bytes gesendet. Bei mir werden die in UTF-8 umgewandelt, welches Umlaute darstellen kann.

Code: Alles auswählen

In [3]: sys.getfilesystemencoding()
Out[3]: 'UTF-8'
Dieses Encoding muss eben in Shell und sys-Modul übereinstimmen, dann kann man print mit Unicode-Objekten bedenkenlos benutzen (Python 2.x).

Ansonsten muss man sie explizit entsprechend encodieren:

Code: Alles auswählen

print unicode_obj.encode(sys.getfilesystemencoding())
Wie immer empfehle ich einen Blick in meine Sig :-)

Re: UnicodeEncodeError

Verfasst: Sonntag 19. Juni 2011, 21:10
von nvidia
ahhh, wieder was gelernt.
Mein encoding ist 'mbcs' .
Mit deiner Methode kann man das ausgeben.
Da krieg ich für den nichtdef. u'\x96' ein Fragezeichen ;-)