¿Cómo se ha podido recuperar un cuerpo de correo electrónico utilizando imaplib en Python?

StackOverflow https://stackoverflow.com/questions/2230037

  •  19-09-2019
  •  | 
  •  

Pregunta

Me gustaría a buscar todo el mensaje desde el servidor IMAP4. En documentación de Python si encontraron esta porción de código que funciona:

>>> t, data = M.fetch('1', '(RFC822)')
>>> body = data[0][1]

Me pregunto si siempre se puede confiar en que los datos [0] [1] devuelve el cuerpo del mensaje. Cuando me he encontrado 'RFC822.SIZE' Tengo sólo una cadena en lugar de una tupla.

He hojeado rfc1730, pero yo no era capaz de averiguar la estructura de respuesta adecuada para la 'RFC822'. También es difícil saber la estructura de resultados buscarlo a la documentación imaplib.

Esto es lo que estoy haciendo al recoger RFC822:

('OK', [('1 (RFC822 {858569}', 'body of the message', ')')])

Pero cuando voy a buscar RFC822.SIZE que estoy recibiendo:

('OK', ['1 (RFC822.SIZE 847403)'])

¿Cómo debo manejar apropiadamente los datos [0] de la lista? ¿Puedo confiar en que cuando se trata de una lista de tuplas la tuplas tiene exactamente 3 partes y la segunda parte es la carga útil?

Tal vez usted sabe mejor biblioteca para IMAP4?

¿Fue útil?

Solución

No se ... imaplib es una muy buena biblioteca, es IMAP que es tan ininteligible.

Es posible que desee comprobar que t == 'OK', pero data[0][1] funciona como se esperaba para tanto como lo he usado.

Aquí está un ejemplo rápido que utilizo para extraer los certificados firmados que he recibido por correo electrónico, no a prueba de bombas, pero se adapta 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

Otros consejos

El IMAPClient paquete es un poco justo más fácil trabajar con ellos. A partir de la descripción:

  

Fácil de usar, Pythonic y completa   biblioteca cliente IMAP.

Esta fue mi solución para extraer los bits de información útiles. Ha sido fiable hasta ahora:

import datetime
import email
import imaplib
import mailbox


EMAIL_ACCOUNT = "your@gmail.com"
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

IMAP herramientas biblioteca para la efectiva uso de los mensajes de correo electrónico utilizando el protocolo IMAP.

  • trabajo transparente con atributos de letras (incluyendo UID)
  • trabajo con letras en directorios (copiar, bandera, movimiento, visto)
  • trabajo con directorios (List, Set obtener, crear, existe, renombrar, borrar, estado)
  • sin dependencias externas
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top