mimemultipart - python email body
¿Cómo puedo obtener el contenido de texto de un mensaje de correo electrónico usando Python? (2)
En un correo electrónico de email.message.Message.get_payload()
, email.message.Message.get_payload()
devuelve una lista con un elemento para cada parte. La forma más fácil es llevar el mensaje y obtener la carga útil de cada parte:
import email
msg = email.message_from_string(raw_message)
for part in msg.walk():
# each part is a either non-multipart, or another multipart message
# that contains further parts... Message is organized like a tree
if part.get_content_type() == ''text/plain'':
print part.get_payload() # prints the raw text
Para un mensaje no multiparte, no es necesario hacer todo el recorrido. Puede ir directamente a get_payload (), independientemente de content_type.
msg = email.message_from_string(raw_message)
msg.get_payload()
Si el contenido está codificado, debe pasar None
como primer parámetro a get_payload()
, seguido de True (el indicador de decodificación es el segundo parámetro). Por ejemplo, supongamos que mi correo electrónico contiene un documento adjunto de MS Word:
msg = email.message_from_string(raw_message)
for part in msg.walk():
if part.get_content_type() == ''application/msword'':
name = part.get_param(''name'') or ''MyDoc.doc''
f = open(name, ''wb'')
f.write(part.get_payload(None, True)) # You need None as the first param
# because part.is_multipart()
# is False
f.close()
En cuanto a obtener una aproximación razonable de texto plano de una parte HTML, he encontrado que html2text funciona bastante bien.
Dado un mensaje RFC822 en Python 2.6, ¿cómo puedo obtener la parte correcta de texto / contenido simple? Básicamente, el algoritmo que quiero es este:
message = email.message_from_string(raw_message)
if has_mime_part(message, "text/plain"):
mime_part = get_mime_part(message, "text/plain")
text_content = decode_mime_part(mime_part)
elif has_mime_part(message, "text/html"):
mime_part = get_mime_part(message, "text/html")
html = decode_mime_part(mime_part)
text_content = render_html_to_plaintext(html)
else:
# fallback
text_content = str(message)
return text_content
De estas cosas, tengo get_mime_part
y has_mime_part
down pat, pero no estoy muy seguro de cómo obtener el texto decodificado de la parte MIME. Puedo obtener el texto codificado usando get_payload()
, pero si trato de utilizar el parámetro de decode
del método get_payload()
(vea el documento ), get_payload()
un error cuando lo llamo en la parte de texto / normal:
File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/ email/message.py", line 189, in get_payload raise TypeError(''Expected list, got %s'' % type(self._payload)) TypeError: Expected list, got <type ''str''>
Además, no sé cómo tomar HTML y presentarlo al texto lo más fielmente posible.
Flat es mejor que anidado;)
from email.mime.multipart import MIMEMultipart
assert isinstance(msg, MIMEMultipart)
for _ in [k.get_payload() for k in msg.walk() if k.get_content_type() == ''text/plain'']:
print _