read - imap python 3
Python Imaplib para obtener los tÃtulos de los temas de la bandeja de entrada de Gmail y el nombre del remitente (4)
Estoy usando pythons imaplib para conectarme a mi cuenta de gmail. Quiero recuperar los 15 mensajes principales (no leídos o leídos, no importa) y mostrar solo los asuntos y el nombre del remitente (o dirección) pero no sé cómo mostrar el contenido de la bandeja de entrada.
Aquí está mi código hasta ahora (conexión exitosa)
import imaplib
mail = imaplib.IMAP4_SSL(''imap.gmail.com'')
mail.login(''[email protected]'', ''somecrazypassword'')
mail.list()
mail.select(''inbox'')
#need to add some stuff in here
mail.logout()
Creo que esto debería ser lo suficientemente simple, simplemente no estoy lo suficientemente familiarizado con los comandos para la biblioteca imaplib. Cualquier ayuda debería ser apreciada ...
ACTUALIZACIÓN gracias a Julian Puedo recorrer cada mensaje y recuperar todo el contenido con:
typ, data = mail.search(None, ''ALL'')
for num in data[0].split():
typ, data = mail.fetch(num, ''(RFC822)'')
print ''Message %s/n%s/n'' % (num, data[0][1])
mail.close()
Pero solo quiero el asunto y el remitente. ¿Hay un comando imaplib para estos elementos o tendré que analizar todo el contenido de los datos [0] [1] para el texto: Asunto y remitente?
ACTUALIZACIÓN: OK, el tema y la parte del remitente funcionaron, pero la iteración (1, 15) se realiza por orden de desconexión, aparentemente me muestra los mensajes más antiguos primero. ¿Cómo puedo cambiar esto? Intenté hacer esto:
for i in range( len(data[0])-15, len(data[0]) ):
print data
pero eso me da None
para las 15 iteraciones ... ¿alguna idea? También probé mail.sort(''REVERSE DATE'', ''UTF-8'', ''ALL'')
pero gmail no admite la función .sort ()
ACTUALIZACIÓN Descubrí una manera de hacerlo:
#....^other code is the same as above except need to import email module
mail.select(''inbox'')
typ, data = mail.search(None, ''ALL'')
ids = data[0]
id_list = ids.split()
#get the most recent email id
latest_email_id = int( id_list[-1] )
#iterate through 15 messages in decending order starting with latest_email_id
#the ''-1'' dictates reverse looping order
for i in range( latest_email_id, latest_email_id-15, -1 ):
typ, data = mail.fetch( i, ''(RFC822)'' )
for response_part in data:
if isinstance(response_part, tuple):
msg = email.message_from_string(response_part[1])
varSubject = msg[''subject'']
varFrom = msg[''from'']
#remove the brackets around the sender email address
varFrom = varFrom.replace(''<'', '''')
varFrom = varFrom.replace(''>'', '''')
#add ellipsis (...) if subject length is greater than 35 characters
if len( varSubject ) > 35:
varSubject = varSubject[0:32] + ''...''
print ''['' + varFrom.split()[-1] + ''] '' + varSubject
¡Esto me da el asunto de los 15 mensajes más recientes y la dirección del remitente en orden decente según se solicite! ¡Gracias a todos los que ayudaron!
Esta fue mi solución para obtener información útil de los correos electrónicos:
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
Estaba buscando un script simple y listo para la lista de la última bandeja de entrada a través de IMAP sin ordenar todos los mensajes. La información aquí es útil, aunque bricolaje y pierde algunos aspectos. Primero, IMAP4.select
devuelve el conteo de mensajes. En segundo lugar, la decodificación del encabezado de asunto no es sencilla.
#! /usr/bin/env python
# -*- coding: utf-8 -*-
import imaplib
import email
from email.header import decode_header
import HTMLParser
# to unescape xml entities
_parser = HTMLParser.HTMLParser()
def decodeHeader(value):
if value.startswith(''"=?''):
value = value.replace(''"'', '''')
value, encoding = decode_header(value)[0]
if encoding:
value = value.decode(encoding)
return _parser.unescape(value)
def listLastInbox(top = 4):
mailbox = imaplib.IMAP4_SSL(''imap.gmail.com'')
mailbox.login(''[email protected]'', ''somecrazypassword'')
selected = mailbox.select(''INBOX'')
assert selected[0] == ''OK''
messageCount = int(selected[1][0])
for i in range(messageCount, messageCount - top, -1):
reponse = mailbox.fetch(str(i), ''(RFC822)'')[1]
for part in reponse:
if isinstance(part, tuple):
message = email.message_from_string(part[1])
yield {h: decodeHeader(message[h]) for h in (''subject'', ''from'', ''date'')}
mailbox.logout()
if __name__ == ''__main__'':
for message in listLastInbox():
print ''-'' * 40
for h, v in message.items():
print u''{0:8s}: {1}''.format(h.upper(), v)
Para aquellos que buscan cómo verificar el correo y analizar los encabezados, esto es lo que usé:
def parse_header(str_after, checkli_name, mailbox) :
#typ, data = m.search(None,''SENTON'', str_after)
print mailbox
m.SELECT(mailbox)
date = (datetime.date.today() - datetime.timedelta(1)).strftime("%d-%b-%Y")
#date = (datetime.date.today().strftime("%d-%b-%Y"))
#date = "23-Jul-2012"
print date
result, data = m.uid(''search'', None, ''(SENTON %s)'' % date)
print data
doneli = []
for latest_email_uid in data[0].split():
print latest_email_uid
result, data = m.uid(''fetch'', latest_email_uid, ''(RFC822)'')
raw_email = data[0][1]
import email
email_message = email.message_from_string(raw_email)
print email_message[''To'']
print email_message[''Subject'']
print email.utils.parseaddr(email_message[''From''])
print email_message.items() # print all headers
c.select(''INBOX'', readonly=True)
for i in range(1, 30):
typ, msg_data = c.fetch(str(i), ''(RFC822)'')
for response_part in msg_data:
if isinstance(response_part, tuple):
msg = email.message_from_string(response_part[1])
for header in [ ''subject'', ''to'', ''from'' ]:
print ''%-8s: %s'' % (header.upper(), msg[header])
Esto debería darle una idea sobre cómo recuperar el tema y desde?