Вопрос:
Это меньшая часть большего проекта. Мне нужно только получить непрочитанные электронные письма и проанализировать их заголовки. Как изменить следующий script, чтобы получать непрочитанные письма?
conn = imaplib.IMAP4_SSL(imap_server) conn.login(imap_user, imap_password) status, messages = conn.select(‘INBOX’) if status != «OK»: print «Incorrect mail box» exit() print messages Лучший ответ:
Что-то вроде этого сделает трюк.
conn = imaplib.IMAP4_SSL(imap_server) try: (retcode, capabilities) = conn.login(imap_user, imap_password) except: print sys.exc_info()[1] sys.exit(1) conn.select(readonly=1) # Select inbox or default namespace (retcode, messages) = conn.search(None, ‘(UNSEEN)’) if retcode == ‘OK’: for num in messages[0].split(‘ ‘): print ‘Processing :’, message typ, data = conn.fetch(num,'(RFC822)’) msg = email.message_from_string(data[0][1]) typ, data = conn.store(num,’-FLAGS’,’\Seen’) if ret == ‘OK’: print data,’n’,30*’-‘ print msg conn.close()
Здесь также есть дублирующий вопрос – Найти новые сообщения, добавленные в почтовый ящик imap, поскольку я последний раз проверял с помощью python imaplib2?
Две полезные функции для извлечения тела и вложений нового обнаруженного вами сообщения (ссылка: Как получить тело электронной почты с помощью imaplib в python?)
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) Ответ №1
Вышеупомянутый ответ больше не работает или, возможно, никогда не делал, но я его модифицировал, поэтому он возвращает только невидимые сообщения, которые он использовал: ошибка не может анализировать команду fetch или что-то вроде этого здесь – рабочий код:
mail = imaplib.IMAP4_SSL(‘imap.gmail.com’) (retcode, capabilities) = mail.login(’email’,’pass’) mail.list() mail.select(‘inbox’) n=0 (retcode, messages) = mail.search(None, ‘(UNSEEN)’) if retcode == ‘OK’: for num in messages[0].split() : print ‘Processing ‘ n=n+1 typ, data = mail.fetch(num,'(RFC822)’) for response_part in data: if isinstance(response_part, tuple): original = email.message_from_string(response_part[1]) print original[‘From’] print original[‘Subject’] typ, data = mail.store(num,’+FLAGS’,’\Seen’) print n
Я думаю, что ошибка исходила от messages[0].split(‘ ‘), но приведенный выше код должен работать нормально.
Также обратите внимание на +FLAGS вместо -FLAGS, который помещает сообщение как прочитанное.
Ответ №2original = email.message_from_string(response_part[1])
Требуется изменить на:
original = email.message_from_bytes(response_part[1]) Ответ №3
Мне удалось заставить это работать с помощью Gmail:
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: %snTo: %snDate: %snSubject: %snnBody: nn%s» %(email_from, email_to,local_message_date, subject, body.decode(‘utf-8’))) output_file.close() else: continue Ответ №4
Вы можете использовать пакет imap_tools:
https://pypi.org/project/imap-tools/
from imap_tools import MailBox, Q with MailBox(‘imap.mail.com’).login(‘test@mail.com’, ‘password’) as mailbox: # get unseen emails from INBOX folder for msg in mailbox.fetch(Q(seen=False)): print(msg.headers)