2009-02-27 8 views
7

La mia applicazione è scritta in python. Quello che sto facendo è che sto eseguendo uno script su ogni e-mail ricevuta da postfix e faccio qualcosa con il contenuto dell'email. Procmail è responsabile per l'esecuzione dello script prendendo l'email come input. Il problema è iniziato quando stavo convertendo il messaggio di input (può essere testo) in oggetto email_message (perché quest'ultimo è utile). Sto usando email.message_from_string (dove email è il modulo email predefinito, fornito con python).Il corpo dell'email è a volte una stringa e talvolta un elenco. Perché?

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

Questa message_body è a volte tornando una lista [esempio email.message.Message, esempio email.message.Message] ea volte restituendo una stringa (contenuto del corpo reale della posta elettronica in arrivo). Perché è così. E anche io ho trovato un'altra osservazione. Quando stavo navigando attraverso la docstring email.message.Message.get_payload(), ho trovato questo ..
"" " Il carico utile può essere un oggetto elenco o una stringa.Se si muta l'oggetto elenco , si modifica il carico utile del messaggio sul posto ..... "" "

Quindi, come posso ottenere un metodo generico per ottenere il corpo dell'email tramite python? Per favore aiutatemi.

risposta

11

Ebbene, le risposte sono corrette, si dovrebbe leggere la documentazione, ma per un esempio di un modo generico:

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() 

Questo è incline a qualche disastro, come è concepibile le parti stesse potrebbero avere multiparts e in realtà restituisce solo la prima parte di testo, quindi anche questo potrebbe essere sbagliato, ma puoi giocarci.

+0

Nella lista dei messaggi di cui ho parlato, ho provato a eseguire get_payload() su ciascuno degli oggetti. Entrambi restituiscono la stessa cosa. Un oggetto è un tipo di clone dell'altro, in modo che se ottengo il get_payload chiamato su una singola parte farà ??? –

+0

Dipende da ciò che è stato inviato. Ad esempio, potresti comunemente ottenere una text/html e una versione text/plain della stessa cosa. È possibile modificare la funzione da cercare e preferire un testo/tipo di contenuto semplice rispetto ad altri tipi di testo. – bobince

+0

impressionante bobince.Hai perfettamente ragione: D –

10

Per quanto folle possa sembrare, la ragione per la stringa di volte, a volte list-semantica è given in the documentation. Fondamentalmente, i messaggi multipart vengono restituiti come liste.

+0

Quello. È. Pazzo. –

9

Piuttosto che semplicemente alla ricerca di un sub-parte, l'uso di cammino() per scorrere il contenuto del messaggio

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

La passeggiata() restituisce un iteratore che si può ciclo con (cioè si tratta di un generatore) . Se il messaggio non è un contenitore di parti (cioè non ha allegati o alterni), il metodo walk() restituirà quindi un iteratore con un singolo elemento: il messaggio stesso.

Si desidera saltare le parti "multipart" poiché sono solo colla.

Il metodo sopra riportato restituisce tutte le parti leggibili. Potresti voler espandere questo per restituire semplicemente le parti di testo se contengono le informazioni che stai cercando.

Nota che a partire da Python 2.5, metodi get_type(), get_main_type(), e get_subtype() sono state rimosse ->http://docs.python.org/library/email.message.html#email.message.Message.walk

+0

Questa è una risposta molto migliore di quella che è stata accettata dall'OP, IMHO. –

+0

Penso che il singolo '=' dovrebbe essere '==' nell'istruzione if – veered

+0

Grazie - corretto – timbo

Problemi correlati