read - ¿Cómo obtener un cuerpo de correo electrónico usando imaplib en python?
python receive email (4)
Biblioteca de imap-tools para un trabajo efectivo con mensajes de correo electrónico utilizando el protocolo IMAP.
- Trabajo transparente con atributos de letras (incluyendo uid).
- trabajar con letras en directorios (copiar, borrar, marcar, mover, visto)
- trabajar con directorios (listar, configurar, obtener, crear, existe, renombrar, eliminar, estado)
- sin dependencias externas
Me gustaría recuperar todo el mensaje del servidor IMAP4. En documentos de Python si se encuentra este bit de código que funciona:
>>> t, data = M.fetch(''1'', ''(RFC822)'')
>>> body = data[0][1]
Me pregunto si siempre puedo confiar en que los datos [0] [1] devuelven el cuerpo del mensaje. Cuando ejecuté ''RFC822.SIZE'' solo tengo una cadena en lugar de una tupla.
Revisé rfc1730 pero no pude averiguar la estructura de respuesta adecuada para el ''RFC822''. También es difícil distinguir la estructura de resultados de búsqueda de la documentación de imaplib.
Esto es lo que estoy obteniendo cuando busco RFC822
:
(''OK'', [(''1 (RFC822 {858569}'', ''body of the message'', '')'')])
Pero cuando RFC822.SIZE
:
(''OK'', [''1 (RFC822.SIZE 847403)''])
¿Cómo debo manejar adecuadamente la lista de datos [0]? ¿Puedo confiar en que cuando se trata de una lista de tuplas, las tuplas tienen exactamente 3 partes y la segunda parte es la carga útil?
¿Tal vez conoces alguna biblioteca mejor para imap4?
El paquete IMAPClient es un poco más fácil de trabajar. De la descripción:
Biblioteca de cliente IMAP fácil de usar, Pythonic y completa.
Esta fue mi solución para extraer los bits útiles de información. Ha sido confiable hasta ahora:
import datetime
import email
import imaplib
import mailbox
EMAIL_ACCOUNT = "[email protected]"
PASSWORD = "your password"
mail = imaplib.IMAP4_SSL(''imap.gmail.com'')
mail.login(EMAIL_ACCOUNT, PASSWORD)
mail.list()
mail.select(''inbox'')
result, data = mail.uid(''search'', None, "UNSEEN") # (ALL/UNSEEN)
i = len(data[0].split())
for x in range(i):
latest_email_uid = data[0].split()[x]
result, email_data = mail.uid(''fetch'', latest_email_uid, ''(RFC822)'')
# result, email_data = conn.store(num,''-FLAGS'',''//Seen'')
# this might work to set flag to seen, if it doesn''t already
raw_email = email_data[0][1]
raw_email_string = raw_email.decode(''utf-8'')
email_message = email.message_from_string(raw_email_string)
# Header Details
date_tuple = email.utils.parsedate_tz(email_message[''Date''])
if date_tuple:
local_date = datetime.datetime.fromtimestamp(email.utils.mktime_tz(date_tuple))
local_message_date = "%s" %(str(local_date.strftime("%a, %d %b %Y %H:%M:%S")))
email_from = str(email.header.make_header(email.header.decode_header(email_message[''From''])))
email_to = str(email.header.make_header(email.header.decode_header(email_message[''To''])))
subject = str(email.header.make_header(email.header.decode_header(email_message[''Subject''])))
# Body details
for part in email_message.walk():
if part.get_content_type() == "text/plain":
body = part.get_payload(decode=True)
file_name = "email_" + str(x) + ".txt"
output_file = open(file_name, ''w'')
output_file.write("From: %s/nTo: %s/nDate: %s/nSubject: %s/n/nBody: /n/n%s" %(email_from, email_to,local_message_date, subject, body.decode(''utf-8'')))
output_file.close()
else:
continue
No ... imaplib
es una biblioteca bastante buena, es imap que es tan ininteligible.
Es posible que desee verificar que t == ''OK''
, pero los data[0][1]
funcionan según lo esperado tanto como lo he usado.
Este es un ejemplo rápido que utilizo para extraer certificados firmados que he recibido por correo electrónico, no a prueba de bombas, pero que se adaptan a mis propósitos:
import getpass, os, imaplib, email
from OpenSSL.crypto import load_certificate, FILETYPE_PEM
def getMsgs(servername="myimapserverfqdn"):
usernm = getpass.getuser()
passwd = getpass.getpass()
subject = ''Your SSL Certificate''
conn = imaplib.IMAP4_SSL(servername)
conn.login(usernm,passwd)
conn.select(''Inbox'')
typ, data = conn.search(None,''(UNSEEN SUBJECT "%s")'' % subject)
for num in data[0].split():
typ, data = conn.fetch(num,''(RFC822)'')
msg = email.message_from_string(data[0][1])
typ, data = conn.store(num,''-FLAGS'',''//Seen'')
yield msg
def getAttachment(msg,check):
for part in msg.walk():
if part.get_content_type() == ''application/octet-stream'':
if check(part.get_filename()):
return part.get_payload(decode=1)
if __name__ == ''__main__'':
for msg in getMsgs():
payload = getAttachment(msg,lambda x: x.endswith(''.pem''))
if not payload:
continue
try:
cert = load_certificate(FILETYPE_PEM,payload)
except:
cert = None
if cert:
cn = cert.get_subject().commonName
filename = "%s.pem" % cn
if not os.path.exists(filename):
open(filename,''w'').write(payload)
print "Writing to %s" % filename
else:
print "%s already exists" % filename