E-Mail entschlüsseln

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
Mr_C
User
Beiträge: 14
Registriert: Samstag 15. Dezember 2018, 13:32

Hallo Zusammen,

ich bin gerade dabei mich in Python einzuarbeiten und versuche mich gerade an folgendem Projekt:
Ich möchte die Verbindung zu einem IMAP Postfach aufnehmen. Anschließend möchte ich alle im Posteingang befindlichen E-Mails (inklusive Anhang) an eine andere Adresse weiterleiten.

Im Projektstatus stehe ich wohl noch ganz am Anfang und muss schon um Hilfe bitten :roll:

Folgendes Problem habe ich:
Ich bekomme die Raw-Daten einer E-Mail nicht in ein lesbares Format umgewandelt. Ich möchte das eigentlich über die email Bibliothek machen...bekomme hier als Antwort jedoch nur "None" wenn ich nach dem Betreff oder Inhalt frage.

Könnt Ihr hier wohl einmal drüber schauen??

Code: Alles auswählen

import imaplib
import email

# An Mailbox anmelden und Posteingang auswählen
mailbox = imaplib.IMAP4("server")
mailbox.login("benutzer", "kennwort")
mailbox.select("INBOX")

# Alle E-Mails im Posteingang suchen
status, daten = mailbox.search(None, "ALL") 

# E-Mail IDs herausfinden und in Liste speichern
ids = daten[0]
id_liste = ids.split()
print(id_liste)

# E-Mail abrufen
status, daten = mailbox.fetch(b"1", "(RFC822)")

# Raw-Daten der E-Mail in Klartext-Daten umwandeln
raw_mail = daten[0][1]

email_msg = email.message_from_string(str(raw_mail))

print(email_msg["Subject"])
print(email_msg["Body"])

# Mailbox schließen und ausloggen
mailbox.close() 
mailbox.logout()
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Statt ``email.message_from_string(str(raw_mail))`` würde ich ja ``email.message_from_bytes(raw_mail)`` nehmen. Bei `str()` ohne eine Kodierung kann sonst was kaputt gehen. Es sollte zwar eigentlich nur ASCII sein, aber es ist halt nicht garantiert.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

Da geht definitiv was kaputt, weil die Repräsentation eines Bytes-Objekts was anderes ist, als ein decodierter String.
Mr_C
User
Beiträge: 14
Registriert: Samstag 15. Dezember 2018, 13:32

Danke für die Antworten. Habe das bereits geändert und die Lösung des Problems gefunden! 8)

Code: Alles auswählen

    # E-Mail dekodieren und in message wandeln
    email_msg = email.message_from_string(raw_mail.decode('windows-1252'))
Wenn man den "windows-1252" Codec nutzt klappt das auch :)
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

Warum nicht `message_from_bytes`?
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Mr_C: Das ist keine Lösung denn das geht kaputt sobald `raw_mail` Daten enthält, die nicht CP1252 kodiert sind.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Mr_C
User
Beiträge: 14
Registriert: Samstag 15. Dezember 2018, 13:32

__blackjack__ hat geschrieben: Montag 17. Dezember 2018, 20:30 @Mr_C: Das ist keine Lösung denn das geht kaputt sobald `raw_mail` Daten enthält, die nicht CP1252 kodiert sind.
Was wäre denn hier die Musterlösung? Da ich den dem Postfach immer nur E-Mails von einem Empfänger erhalte würde es erstmal funktionieren...


Gibt es irgendwo eine Auflistung an Suchbefehle für den .search() Befehl?

Code: Alles auswählen

# Alle E-Mails im Posteingang suchen
status, daten = mailbox.search(None, "ALL") 
Ich würde gerne alle E-Mails suchen, welche älter als eine Stunde sind. Somit könnte ich das Programm alle 30 Minuten aufrufen und er verschiebt nur die alten E-Mails in ein anderes Postfach.
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Die Musterlösung ist `message_from_bytes()`. Du hast Bytes, Du willst ein `Message`-Objekt, diese Funktion macht genau das. Nicht das die hier schon mal erwähnt wurde oder so… :twisted:

Die Liste aller Suchbefehle steht im IMAP-RFC.

Ich würde übrigens nicht `imaplib` direkt verwenden. Das ist nur eine ziemlich dünne Schicht die das IMAP-Protokoll implementiert, also nicht wirklich benutzerfreundlich. `imapclient` baut da noch ein bisschen drüber. Das ist sozusagen für IMAP das was `requests` für `urllib` & Co ist.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Mr_C
User
Beiträge: 14
Registriert: Samstag 15. Dezember 2018, 13:32

Alles klar, hab das ganze nun mit message_from_bytes() gemacht. Funktioniert 100%ig! Danke für die Unterstützung!
Antworten