Python Email Anhang auslesen

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
oxi
User
Beiträge: 6
Registriert: Mittwoch 1. Dezember 2010, 10:52

Hallo liebe Community,

ich schreibe gerade ein Python-Server, der Emails von einem POP3 Server abholt und in eine MYSQL-Datenbank schreiben soll.
Ich bin soweit, dass ich die Emails abrufen kann und in eine MYSQL-Datenbank schreiben kann.

Hier der Code zum abrufen der Emails:

Code: Alles auswählen

def mail_abholen():    
    server = poplib.POP3('SERVER')
    stdout = server.getwelcome()
    stdout = server.user('USER')
    stdout = server.pass_('PASSWORT')
    
    msg = server.retr(1)
    str = string.join(msg[1], "\n")
    mail = email.message_from_string(str)
Nun möchte ich gerne die Anhänge der Mails mit einlesen und auch in eine MYSQL-Datenbank einlesen. Wie kann ich das realisieren?

Viele Grüße
Alex
svenXY
User
Beiträge: 27
Registriert: Dienstag 16. Juni 2009, 10:36
Kontaktdaten:

email.message.walk gibt Dir Zugriff auf die einzelnen Mime-Parts einer Multipart-Mail.
oxi
User
Beiträge: 6
Registriert: Mittwoch 1. Dezember 2010, 10:52

Erst einmal vielen Dank für deine schnelle Antwort.

Wenn ich dies nun mit einbaue, gibt er mir bei einer beispiel Email folgendes aus:

Code: Alles auswählen

multipart/mixed
text/plain
message/rfc822
multipart/alternative
text/plain
text/html
Bei einem Zweitem Beispiel folgendes:

Code: Alles auswählen

multipart/mixed
text/plain
application/pdf
Wie kann ich nun diese Anhänge auslesen und in eine Datenbank schreiben?
svenXY
User
Beiträge: 27
Registriert: Dienstag 16. Juni 2009, 10:36
Kontaktdaten:

ohne jetzt nochmal in die Doku für das email-Modul zu schauen, Du bekommst mit walk() einen _Iterator über die einzelnen Parts Deioner Multipart-Message. Sie kommen als Message-Objekte, die Du mit den entsprechenden Funktionen auslesen und manipulieren kannst.

Aus der Doku:
"Here’s an example of how to unpack a MIME message like the one above, into a directory of files"

Statt die "Dateien" zu speichern musst Du sie halt in Deine DB schreiben
oxi
User
Beiträge: 6
Registriert: Mittwoch 1. Dezember 2010, 10:52

Hallo,

in der Doku habe ich nichts dementsprechendes gefunden. Es tut mir leit wenn ich gerade blind auf den Augen bin, aber ich finde dort nichts.
Wie heißt denn genau die Methode um den Anhang in eine Datei einzulesen/encodieren?
svenXY
User
Beiträge: 27
Registriert: Dienstag 16. Juni 2009, 10:36
Kontaktdaten:

Du hast nicht wirklich selbst was probiert, oder?
get_payload() ist Dein Freund.

Aaaaaalso:

Code: Alles auswählen

    for part in msg.walk():
        # multipart/* are just containers
        if part.get_content_maintype() == 'multipart':
            continue
        # Applications should really sanitize the given filename so that an
        # email message can't be used to overwrite important files
        filename = part.get_filename()
        if not filename:
            ext = mimetypes.guess_extension(part.get_content_type())
            if not ext:
                # Use a generic bag-of-bits extension
                ext = '.bin'
            filename = 'part-%03d%s' % (counter, ext)
        counter += 1

        #### hier wird dann der Inhalt des Parts in eine Datei geschrieben,
        #### stattdessen musst Du das dann eben in die Datenbank schreiben:

        fp = open(os.path.join(opts.directory, filename), 'wb')
        fp.write(part.get_payload(decode=True))
        fp.close()

Das sollte Dir auf die Sprünge helfen. Anpassen wirst Du es schon selbst müssen.
oxi
User
Beiträge: 6
Registriert: Mittwoch 1. Dezember 2010, 10:52

Ah Super vielen vielen Dank!

Nun zu leider noch ein weiteres Problemen:

Code: Alles auswählen

fp.write(part.get_payload(decode=True))
TypeError: argument 1 must be string or buffer, not None
Was könnte das bedeuten? Es handelt sich hier um eine SPAM-Nachricht, die von meinem Mail-Server erkannt wurde und im Anhang die original-Message hat.
svenXY
User
Beiträge: 27
Registriert: Dienstag 16. Juni 2009, 10:36
Kontaktdaten:

aus irgendeinem Grund bekommst Du von get_payload() hier nichts zurück. Du wirst es debuggen müssen.
oxi
User
Beiträge: 6
Registriert: Mittwoch 1. Dezember 2010, 10:52

ah ok.
in der Message, wenn es ein possible Spam ist, ist im Anhang eine .html datei und eine .txt Datei.
Aber vielen Dank!
svenXY
User
Beiträge: 27
Registriert: Dienstag 16. Juni 2009, 10:36
Kontaktdaten:

es wird wohl noch eine multipart-messayge in der eigentlichen multipart-message sein. Möglicherweise musst Du das entsprechend abfangen.
oxi
User
Beiträge: 6
Registriert: Mittwoch 1. Dezember 2010, 10:52

ja das ist hier immer 3fach verschachtelt. kann ich sowas denn auch abspeichern? hast du da erfahrungen?
svenXY
User
Beiträge: 27
Registriert: Dienstag 16. Juni 2009, 10:36
Kontaktdaten:

ich habe damit bisher noch praktisch nix gemacht, aber Du musst die Funktion dann wohl rekursiv einsetzen, damit auch die Parts wieder geprüft werden, ob sie multiparts sind usw. Wenn Du etwas googlest wirst Du sicher Lösungen finden, wie man emails mit python komplett auseinandernimmt

http://www.osvisnet.co.cc/index.php?opt ... &Itemid=29 war der erste Versuch, sieht aber vielversprechend aus:
Python has an impressive email handling capability providing you actually understand the structure of email messages. [...] the parts themselves can have sub-parts. In order to 'put them all back together' we need to process them recursively.
Antworten