2009-02-27 8 views
7

Meine Anwendung ist in Python geschrieben. Was ich mache ist, dass ich ein Skript für jede E-Mail, die ich per Postfix erhalten habe, mache und etwas mit dem E-Mail-Inhalt mache. Procmail ist verantwortlich für das Ausführen des Skripts, wobei die E-Mail als Eingabe genommen wird. Das Problem begann, als ich die Eingabe-Nachricht (möglicherweise Text) in ein email_message-Objekt konvertierte (weil Letzteres nützlich ist). Ich verwende email.message_from_string (wobei E-Mail das Standard-E-Mail-Modul ist, kommt mit Python).E-Mail-Körper ist manchmal eine Zeichenfolge und manchmal eine Liste. Warum?

import email message = email.message_from_string(original_mail_content) message_body = message.get_payload()

Diese message_body manchmal kehrt eine Liste [email.message.Message Beispiel email.message.Message Instanz] und irgendwann einen String (tatsächlicher Körper Inhalt der eingehenden E-Mail) zurück. Warum ist es. Und sogar ich fand eine weitere Beobachtung. Als ich durch die Email-Nachricht email.message.Message.get_payload() stöberte, fand ich diese .. " Die Nutzlast wird entweder ein Listenobjekt oder eine Zeichenkette sein. Wenn Sie das Listenobjekt mutieren, ändern Sie die Nutzinformation der Nachricht an Ort und Stelle ..... "" "

Also, wie habe ich generische Methode, um den Körper der E-Mail durch Python zu bekommen? Bitte hilf mir.

Antwort

11

Nun, die Antworten richtig sind, sollten Sie die Dokumentation lesen, aber für ein Beispiel einer generischen Art und Weise:

def get_first_text_part(msg): 
    maintype = msg.get_content_maintype() 
    if maintype == 'multipart': 
     for part in msg.get_payload(): 
      if part.get_content_maintype() == 'text': 
       return part.get_payload() 
    elif maintype == 'text': 
     return msg.get_payload() 

Dies ist anfällig für einige Katastrophe, wie es die Teile ist denkbar, selbst multiparts haben könnte , und es gibt wirklich nur den ersten Textteil zurück, also könnte das auch falsch sein, aber Sie können damit spielen. Vielmehr

+0

In der Nachrichtenliste, über die ich gesprochen habe, habe ich versucht, get_payload() für jedes der Objekte auszuführen. Beide bringen dasselbe zurück. Ist ein Objekt Art von Klon des anderen, so dass, wenn ich Get_Payload an einem einzigen Teil aufgerufen bekomme ??? –

+0

Hängt davon ab, was Sie gesendet haben. Sie könnten zum Beispiel häufig eine text/html- und eine text/plain-Version der gleichen Sache bekommen. Sie könnten die Funktion ändern, um nach einem Text/einfachen Inhaltstyp zu suchen und ihn einem anderen Text/Typ vorzuziehen. – bobince

+0

Super Bobince.Sie haben absolut Recht: D –

10

So verrückt sehen, wie es der Grund für die manchmal Zeichenfolge könnte scheinen, manchmal list-Semantik ist given in the documentation. Grundsätzlich werden mehrteilige Nachrichten als Listen zurückgegeben.

+0

das. Ist. Verrückt. –

9

als einfach auf der Suche nach einem Unterteil, Verwendung zu Fuß() iterieren durch die Nachrichteninhalte

def walkMsg(msg): 
    for part in msg.walk(): 
    if part.get_content_type() == "multipart/alternative": 
     continue 
    yield part.get_payload(decode=1) 

Die Wanderung() Methode gibt einen Iterator, dass Sie kann Schleife mit (dh es ist ein Generator) . Wenn die Nachricht kein Container aus Teilen ist (d. H. Keine Anhänge oder Alternativen hat), gibt die Methode walk() einen Iterator mit einem einzelnen Element zurück - die Nachricht selbst.

Sie möchten 'mehrteilige' Teile überspringen, da sie nur Leim sind.

Die obige Methode gibt alle lesbaren Teile zurück. Sie können dies erweitern, um einfach die Textteile zurückzugeben, wenn sie die Informationen enthalten, nach denen Sie suchen.

Beachten Sie, dass wie von Python 2.5, Methoden GET_TYPE(), get_main_type() und get_subtype() entfernt wurden ->http://docs.python.org/library/email.message.html#email.message.Message.walk

+0

Dies ist eine viel bessere Antwort als die, die vom OP angenommen wurde, IMHO. –

+0

Ich denke, dass Single '=' sollte '==' in der if-Anweisung sein – veered

+0

Danke - korrigiert – timbo