2009-02-27 19 views
7

Mi aplicación está escrita en python. Lo que estoy haciendo es ejecutar un script en cada correo electrónico recibido por postfix y hacer algo con el contenido del correo electrónico. Procmail es responsable de ejecutar el script tomando el correo electrónico como entrada. El problema comenzó cuando estaba convirtiendo el mensaje de entrada (puede ser texto) a objeto email_message (porque este último es útil). Estoy usando email.message_from_string (donde el correo electrónico es el módulo de correo electrónico predeterminado, viene con python).El cuerpo del correo electrónico es a veces una cadena y una lista. ¿Por qué?

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

Este message_body a veces se vuelve una lista [email.message.Message ejemplo, instancia email.message.Message] y en algún momento regresar una cadena (contenido propio cuerpo del correo electrónico entrante). Porque es E incluso encontré una observación más. Cuando estaba navegando a través de la carpeta docstring email.message.Message.get_payload(), encontré esto ...
"" " La carga útil será un objeto de lista o una cadena.Si modifica el objeto de lista , modifique la carga útil del mensaje en su lugar ... "" "

Entonces, ¿cómo puedo tener un método genérico para obtener el cuerpo del correo electrónico a través de python? Por favor, ayúdame.

Respuesta

11

Bueno, las respuestas son correctas, debería leer la documentación, pero para un ejemplo de una forma genérica:

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

Esta es propenso a algún desastre, ya que es concebible las propias piezas podrían tener Multiparts , y realmente solo devuelve la primera parte del texto, por lo que también podría estar mal, pero puedes jugar con ella.

+0

En la lista de mensajes de la que hablé, intenté ejecutar get_payload() en cada uno de los objetos. Ambos devuelven lo mismo. ¿Es un objeto tipo de clon del otro, de modo que si obtengo el get_payload invocado, una sola parte lo hará? –

+0

Depende de lo que le han enviado. Comúnmente, por ejemplo, puede obtener un texto/html y una versión de texto/simple de la misma cosa. Puede modificar la función para buscar y prefiere un texto/tipo de contenido simple sobre otros texto/tipos. – bobince

+0

Bobince impresionante.Tiene toda la razón: D –

10

Tan loco como podría parecer, la razón de la cadena a veces, a veces list-semántica es given in the documentation. Básicamente, los mensajes multiparte se devuelven como listas.

+0

Eso. Es. Loca. –

9

En lugar de simplemente buscar una subparte, paseo uso() para recorrer el contenido del mensaje

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

El paseo() devuelve un iterador que puede recorrer con (es decir, se trata de un generador) . Si el mensaje no es un contenedor de partes (es decir, no tiene archivos adjuntos o alternativas), el método walk() devolverá un iterador con un solo elemento: el mensaje en sí.

Desea omitir las piezas 'multipartes', ya que son simplemente pegamento.

El método anterior devuelve todas las partes legibles. Es posible que desee expandir esto para simplemente devolver las partes de texto si contienen la información que está buscando.

Nota que a partir de Python 2.5, métodos get_type(), get_main_type(), y get_subtype() se han eliminado ->http://docs.python.org/library/email.message.html#email.message.Message.walk

+0

Esta es una respuesta mucho mejor que la que fue aceptada por el OP, en mi humilde opinión. –

+0

Creo que solo '=' debe ser '==' en la instrucción if – veered

+0

Gracias - corregido – timbo

Cuestiones relacionadas