2009-02-27 4 views
7

Mon application est écrite en python. Ce que je fais est que je cours un manuscrit sur chaque email reçu par postfix et fait quelque chose avec le contenu d'email. Procmail est responsable de l'exécution du script en prenant l'email comme entrée. Le problème a commencé lors de la conversion du message d'entrée (peut-être du texte) en objet email_message (car ce dernier est très pratique). J'utilise email.message_from_string (où email est le module email par défaut, livré avec python).Email corps est une chaîne parfois et une liste parfois. Pourquoi?

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

Ce message_body revient parfois une liste [par exemple email.message.Message, par exemple email.message.Message] et revenir quelque temps une chaîne (contenu du corps réel de l'e-mail entrant). Pourquoi est-ce. Et même j'ai trouvé une observation de plus. Lorsque je parcourais la docstring email.message.Message.get_payload(), je l'ai trouvé ..
"" " La charge utile sera soit un objet de liste ou une chaîne.Si vous mutez l'objet liste, vous modifiez la charge utile du message en place ..... "" "

Alors, comment ai-je une méthode générique pour obtenir le corps de l'email via Python? Sil te plait aide moi.

Répondre

11

Eh bien, les réponses sont correctes, vous devriez lire les documents, mais pour un exemple d'une manière générique:

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

C'est sujette à une catastrophe, car il est concevable les parties elles-mêmes pourraient avoir multiparts , et cela ne fait que renvoyer la première partie du texte, donc cela peut aussi être faux, mais vous pouvez jouer avec.

+0

Dans la liste des messages dont j'ai parlé, j'ai essayé d'exécuter get_payload() sur chacun des objets. Les deux retournent la même chose. Est-ce qu'un type d'objet est un clone de l'autre, de sorte que si je reçois le get_payload appelé, une seule partie fera l'affaire ??? –

+0

Cela dépend de ce que vous avez reçu. Vous pouvez généralement, par exemple, obtenir un texte/html et un texte/version simple de la même chose. Vous pouvez modifier la fonction à rechercher et préférer un type de texte/type de contenu par rapport aux autres types de texte. – bobince

+0

Impressionnant bobince.Vous avez absolument raison: D –

10

Aussi fou que cela puisse paraître, la raison de la chaîne parfois, parfois liste-sémantique sont given in the documentation. Fondamentalement, les messages multipart sont renvoyés sous forme de listes.

+0

Ce. Est. Fou. –

9

Plutôt que de chercher simplement une sous-partie, l'utilisation à pied() pour itérer le contenu du message

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

La méthode de marche() retourne un itérateur que vous pouvez faire une boucle avec (il est un générateur) . Si le message n'est pas un conteneur de parties (c'est-à-dire n'a pas de pièces jointes ou de variantes), la méthode walk() retournera alors un itérateur avec un seul élément - le message lui-même.

Vous souhaitez ignorer les pièces «en plusieurs parties» car elles ne sont que de la colle.

La méthode ci-dessus renvoie toutes les parties lisibles. Vous voudrez peut-être étendre ceci pour simplement retourner les parties de texte si elles contiennent l'information que vous recherchez.

Notez que depuis Python 2.5, les méthodes get_type(), get_main_type(), et get_subtype() ont été enlevés ->http://docs.python.org/library/email.message.html#email.message.Message.walk

+0

C'est une bien meilleure réponse que celle qui a été acceptée par le PO, à mon humble avis. –

+0

Je pense que le simple '=' devrait être '==' dans l'instruction if – veered

+0

Merci - corrigé – timbo

Questions connexes