2010-02-09 40 views
16

Me gustaría recuperar todo el mensaje del servidor IMAP4. En documentación de Python si encontraron esta porción de código que funciona:¿Cómo recuperar un cuerpo de correo electrónico usando imaplib en python?

>>> 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 he ejecutado 'RFC822.SIZE' tengo solo una cadena en lugar de una tupla.

He revisado rfc1730 pero no pude determinar 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.

Aquí es lo que quiero llegar 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] Lista ? ¿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?

¿Quizás conoces alguna biblioteca mejor para imap4?

+0

si u recuperado correctamente el cuerpo del correo puede usted por favor compartir el código? – hussain

Respuesta

19

No ... imaplib es una biblioteca bastante buena, es imap que es tan ininteligible.

Es posible que desee comprobar que t == 'OK', pero data[0][1] funciona como se esperaba 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 
+0

Es bueno saber que esto funciona para usted. Pero alguna idea de por qué funciona como se describe? –

+0

Los valores de retorno son la respuesta del servidor IMAP tokenizado. – MattH

+0

Es de suponer que las bibliotecas imap de alto nivel deben lidiar con fallas entre las diferentes implementaciones de imap o ser incompatibles. – MattH

7

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

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

+0

Lo apoyo. IMAPClient es muy útil y orientado a objetos. Es mucho más fácil de usar que imaplib y no tiene problemas importantes. – zoobert

0

Esta fue mi solución para extraer los bits útiles de información. Ha sido fiable 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 
0

imap-tools biblioteca eficaz 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
Cuestiones relacionadas