Seite 1 von 1
Unicode problem mit ImapClient, die zweite
Verfasst: Dienstag 3. Juni 2014, 17:33
von beatrix.w
Hallo,
Python-Newbie hier. Bin mit meinem Script zum Abfragen einer Mailbox mit der ImapClient-Library schon recht weit gekommen. Aber irgendwie verstehe ich die Encodings in Python immer noch nicht korrekt. Der Code ist der folgende:
Code: Alles auswählen
msgdict = imap_connection.fetch(messages[current_mail - 1], ['BODY.PEEK[]'])
for message_id, message in msgdict.items():
temp_folderitem, temp_path = tempfile.mkstemp()
try:
temp_binarystream = os.fdopen(temp_folderitem,'w')
temp_binarystream.write(message['BODY[]'].encode('utf8', 'ignore'))
except IOError, err:
print "xxxerrorxxx: IOError:" + temp_path, err
sys.exit(1)
#end try
temp_binarystream.close()
print 'file:' + temp_path
Das Problem liegt in der Zeile
Code: Alles auswählen
temp_binarystream.write(message['BODY[]'].encode('utf8', 'ignore'))
Das verändert mir den MessageBody soweit, daß ich ihn in meinem Parser nicht parsen kann bei einigen Mails, z.B. in russisch. Im Hex-Editor kann ich erkennen, daß die originale Datei, die ich in AppleMail habe, mit den Daten aus message['BODY[]'] übereinstimmt. Wenn ich das encode weglasse, meckert Python über nicht encodierbares ascii.
Wie kann ich Python dazu bringen, daß er mir die original Daten schreibt und nicht die - im Fall der russischen Mail - Daten neu encodiert?
Grüße
Beatrix Willius
Re: Unicode problem mit ImapClient, die zweite
Verfasst: Dienstag 3. Juni 2014, 18:46
von BlackJack
@beatrix.w: Das kommt ganz darauf an was die Originaldaten sind. Was hat ``message['BODY[]']`` denn für einen Typ? Wenn das `unicode` ist, dann hast Du schon ”verloren”. Falls es ein Bytestring ist macht das `encode()` so gar keinen Sinn.
Eine Datei die an den Namen `temp_binarystream` gebunden ist, würde ich übrigens auch im Binärmodus öffnen.
Re: Unicode problem mit ImapClient, die zweite
Verfasst: Mittwoch 4. Juni 2014, 16:03
von beatrix.w
Der String ist ein Unicode-String - laut Debugger. Wieso habe ich dann verloren? Kann ich einem String in Python nicht sagen, daß er sein Encoding vergessen soll?
Beginn der kyrillischen Mail (wahrscheinlich Spam): Соберем для
Beginn der Mail in AppleMail in hex: D1 EE E1
Beginn der Mail in Python im Debugger: \xd1\xee\xe1\
Begin der Mail in Python in hex in Datei geschrieben: C3 91 C3 AE C3
Die Daten sehen vor dem Rausschreiben okay aus. Aber wie komme ich da dran?
Grüße
Beatrix Willius
Re: Unicode problem mit ImapClient, die zweite
Verfasst: Mittwoch 4. Juni 2014, 17:13
von BlackJack
@beatrix.w: Wenn der Wert schon `unicode` ist, dann sind die Daten bereits dekodiert und an der `unicode`-Zeichenkette selber kann man nicht mehr erkennen welche Kodierung das ursprünglich mal war. Wobei die Dekodierung auch irgendwie nicht zu den Daten passt. Das sieht aus wie dekodiert ohne tatsächlich zu dekodieren, also einfach Bytewert zu Codepoint.
Re: Unicode problem mit ImapClient, die zweite
Verfasst: Mittwoch 4. Juni 2014, 17:18
von Sirius3
Du dekodierst die Daten als Latin-1 und schreibst sie wieder als UTF8 kodiert in die Datei. Da kann dann natürlich nur Murx rauskommen.
Re: Unicode problem mit ImapClient, die zweite
Verfasst: Mittwoch 4. Juni 2014, 17:27
von BlackJack
@Sirius3: Das Problem dabei ist ja das die Daten nicht von beatrix.w dekodiert werden, also der Schritt nicht bewusst gemacht wird. Ich vermute mal ganz stark das die Daten in der Mail schon fehlerhaft sind, also dort Kodierungsangabe und die tatsächliche Kodierung der Daten nicht zusammen passen. Also zum Beispiel gar keine Kodierungsangabe drin steht, also implizit latin-1, der Text selber aber cp1251 kodiert ist.
Re: Unicode problem mit ImapClient, die zweite
Verfasst: Donnerstag 5. Juni 2014, 15:42
von beatrix.w
@Blackjack: nein, die Daten sind nicht fehlerhaft. Bei Mails steht die Kodierung im Content Transfer Encoding. Aber einzelne Teile einer Mail können unterschiedliche Encodings haben. Also muß man erst die einzelnen Teile einer Mail trennen und am Schluß bekommen die Teilstücke die Kodierung verpaßt.
An dieser Stelle bin ich noch weit davon entfernt, an das Content Transfer Encoding zu kommen. Daher kann ich nicht so einfach eine beliebige Kodierung nehmen.
Re: Unicode problem mit ImapClient, die zweite
Verfasst: Donnerstag 5. Juni 2014, 15:56
von BlackJack
@beatrix.w: Also noch mal die Frage: was ist das überhaupt für ein Typ, denn ich bekomme da für den Schlüssel 'BODY[]' den Typ `str` und nicht `unicode`. Warum hast Du da `unicode`?
Re: Unicode problem mit ImapClient, die zweite
Verfasst: Donnerstag 5. Juni 2014, 16:05
von beatrix.w
message ist ein Dictionary. message['BODY[]'] ist unicode - sagt der Debugger.
Das kommt vom ImapClient. So wirklich viel mache ich da doch gar nicht.
Re: Unicode problem mit ImapClient, die zweite
Verfasst: Donnerstag 5. Juni 2014, 16:23
von BlackJack
@beatrix.w: OMG, ich habe gerade IMAPClient aktualisiert (von 0.8 auf 0.11) und das macht IMAPClient ja tatsächlich. Warum nur!? Und mit welcher Kodierung? Das ist ja krank. Und kaputt.
Re: Unicode problem mit ImapClient, die zweite
Verfasst: Donnerstag 5. Juni 2014, 16:37
von BlackJack
Und nochmal: Es ist tatsächlich kaputt:
http://librelist.com/browser//imapclien ... s-strings/
Bedeutet für Dich jetzt wahrscheinlich erst einmal, dass Du die Daten wieder als 'latin-1' kodieren musst und hoffen musst, dass Dir keine Mails unterkommen bei denen das irgendwie auf die Nase fällt oder kaputte Daten produziert.
Re: Unicode problem mit ImapClient, die zweite
Verfasst: Donnerstag 5. Juni 2014, 16:45
von beatrix.w
Hahahha..........danke für's testen.
Ich habe schon versucht, den Author zu kontaktieren. Aber bisher ohne Erfolg. Und nein, meine Emails (und die meiner Kunden) können alle möglichen Encodings haben. Wie z.B. die russische, mit der ich schon getestet habe.
Wäre auch mit einem einigermaßen schnell-laufenden Workaround zufrieden. Werde mir mal den Link ansehen.