library - sent email from python
Extraer el cuerpo de un correo electrónico del archivo mbox, decodificarlo en texto sin formato, independientemente de Charset y Content Transfer Encoding (2)
Aquí hay un código que hace el trabajo, imprime errores en lugar de bloquearse para aquellos mensajes donde fallaría. Espero que pueda ser útil. Tenga en cuenta que si hay un error en Python 3, y eso es fijo, entonces las líneas .get_payload (decode = True) pueden devolver un objeto str en lugar de un objeto bytes. Ejecuté este código hoy en 2.7.2 y en Python 3.2.1.
import mailbox
def getcharsets(msg):
charsets = set({})
for c in msg.get_charsets():
if c is not None:
charsets.update([c])
return charsets
def handleerror(errmsg, emailmsg,cs):
print()
print(errmsg)
print("This error occurred while decoding with ",cs," charset.")
print("These charsets were found in the one email.",getcharsets(emailmsg))
print("This is the subject:",emailmsg[''subject''])
print("This is the sender:",emailmsg[''From''])
def getbodyfromemail(msg):
body = None
#Walk through the parts of the email to find the text body.
if msg.is_multipart():
for part in msg.walk():
# If part is multipart, walk through the subparts.
if part.is_multipart():
for subpart in part.walk():
if subpart.get_content_type() == ''text/plain'':
# Get the subpart payload (i.e the message body)
body = subpart.get_payload(decode=True)
#charset = subpart.get_charset()
# Part isn''t multipart so get the email body
elif part.get_content_type() == ''text/plain'':
body = part.get_payload(decode=True)
#charset = part.get_charset()
# If this isn''t a multi-part message then get the payload (i.e the message body)
elif msg.get_content_type() == ''text/plain'':
body = msg.get_payload(decode=True)
# No checking done to match the charset with the correct part.
for charset in getcharsets(msg):
try:
body = body.decode(charset)
except UnicodeDecodeError:
handleerror("UnicodeDecodeError: encountered.",msg,charset)
except AttributeError:
handleerror("AttributeError: encountered" ,msg,charset)
return body
#mboxfile = ''C:/Users/Username/Documents/Thunderbird/Data/profile/ImapMail/server.name/INBOX''
print(mboxfile)
for thisemail in mailbox.mbox(mboxfile):
body = getbodyfromemail(thisemail)
print(body[0:1000])
Estoy tratando de usar Python 3 para extraer el cuerpo de los mensajes de correo electrónico de un archivo thunderbird mbox. Es una cuenta IMAP.
Me gustaría tener el texto como parte del cuerpo del correo electrónico disponible para procesar como una cadena Unicode. Debería ''parecerse'' a lo que el correo electrónico hace en Thunderbird, y no contener caracteres escapados como / r / n = 20, etc.
Creo que son las codificaciones de transferencia de contenido las que no sé cómo descodificar o eliminar. Recibo correos electrónicos con una variedad de diferentes tipos de contenido y diferentes codificaciones de transferencia de contenido. Este es mi intento actual:
import mailbox
import quopri,base64
def myconvert(encoded,ContentTransferEncoding):
if ContentTransferEncoding == ''quoted-printable'':
result = quopri.decodestring(encoded)
elif ContentTransferEncoding == ''base64'':
result = base64.b64decode(encoded)
mboxfile = ''C:/Users/Username/Documents/Thunderbird/Data/profile/ImapMail/server.name/INBOX''
for msg in mailbox.mbox(mboxfile):
if msg.is_multipart(): #Walk through the parts of the email to find the text body.
for part in msg.walk():
if part.is_multipart(): # If part is multipart, walk through the subparts.
for subpart in part.walk():
if subpart.get_content_type() == ''text/plain'':
body = subpart.get_payload() # Get the subpart payload (i.e the message body)
for k,v in subpart.items():
if k == ''Content-Transfer-Encoding'':
cte = v # Keep the Content Transfer Encoding
elif subpart.get_content_type() == ''text/plain'':
body = part.get_payload() # part isn''t multipart Get the payload
for k,v in part.items():
if k == ''Content-Transfer-Encoding'':
cte = v # Keep the Content Transfer Encoding
print(body)
print(''Body is of type:'',type(body))
body = myconvert(body,cte)
print(body)
Pero esto falla con:
Body is of type: <class ''str''>
Traceback (most recent call last):
File "C:/Users/David/Documents/Python/test2.py", line 31, in <module>
body = myconvert(body,cte)
File "C:/Users/David/Documents/Python/test2.py", line 6, in myconvert
result = quopri.decodestring(encoded)
File "C:/Python32/lib/quopri.py", line 164, in decodestring
return a2b_qp(s, header=header)
TypeError: ''str'' does not support the buffer interface
Este script parece devolver todos los mensajes correctamente:
def getcharsets(msg):
charsets = set({})
for c in msg.get_charsets():
if c is not None:
charsets.update([c])
return charsets
def getBody(msg):
while msg.is_multipart():
msg=msg.get_payload()[0]
t=msg.get_payload(decode=True)
for charset in getcharsets(msg):
t=t.decode(charset)
return t
La respuesta anterior de acd a menudo devuelve solo un pie de página del mensaje real. (al menos en los mensajes de correo electrónico de GMANE estoy abriendo para esta caja de herramientas: https://pypi.python.org/pypi/gmane )
aclamaciones