Читаем почту через IMAP в Python







У меня не вышло найти всю необходимую информацию об IMAP в интернете, кроме RFC3501. Документ протокола IMAP Python – ключ к пониманию доступных пользователю команд, однако позвольте пропустить попытки объяснить все сразу, и лучше взглянем на пример, где я смогу объяснить основные принципы работы
Заходим в почтовый ящик
import imaplib
mail = imaplib.IMAP4_SSL('imap.gmail.com')
mail.login('myusername@gmail.com', 'mypassword')
mail.list()
# Выводит список папок в почтовом ящике.
mail.select("inbox") # Подключаемся к папке "входящие".
- Выбираем последние письма
- Начнем с поиска входящих среди всех писем при помощи функции поиска
- Воспользуемся встроенным ключом “ALL”, чтобы получить все результаты (документировано в RFC3501)
Далее мы извлечем необходимые нам данные из ответа, затем получим почту, через вычисленный нами ID.
result, data = mail.search(None, "ALL")
ids = data[0] # Получаем сроку номеров писем
id_list = ids.split() # Разделяем ID писем
latest_email_id = id_list[-1] # Берем последний ID
result, data = mail.fetch(latest_email_id, "(RFC822)") # Получаем тело письма (RFC822) для данного ID
raw_email = data[0][1] # Тело письма в необработанном виде
# включает в себя заголовки и альтернативные полезные нагрузки
Используем UID вместо ID
Функция поиска imap возвращает последовательный ID: если значение ID равно 5, значит это пятый электронный адрес в вашей почте. Это значит, что когда пользователь удаляет адрес под номером 10, все письма, находящиеся выше этой отметки указывают на неправильный адрес.
Это неприемлемо!
Не можете найти дешевых подписчиков в YouTube с гарантиями? Предлагаем Вам обратиться за помощью по ссылке и сделать выгодную покупку на надежном сайте SMM услуг. Здесь Вы получите качественный гарантированный ресурс по заманчивым ценам.
К счастью, мы можем отправить запрос на сервер imap и вернуть уникальный id (UID). Это работает очень просто: мы используем функцию uid и передаём её строке команды in в качестве первого аргумента. Остальная часть кода остается неизменной.
result, data = mail.uid('search', None, "ALL") # Выполняет поиск и возвращает UID писем.
latest_email_uid = data[0].split()[-1]
result, data = mail.uid('fetch', latest_email_uid, '(RFC822)')
raw_email = data[0][1]
Анализ необработанных писем
Работа с почтой очень похожа на разбор невнятной речи. К счастью, мы располагаем библиотекой python для работы с почтой, которая называется, кто бы мог подумать, email. Данная библиотека может конвертировать необработанные письма в знакомый нам объект EmailMessage.
import email
email_message = email.message_from_string(raw_email)
print email_message['To']
print email.utils.parseaddr(email_message['From']) # получаем имя отправителя "Yuji Tomita"
print email_message.items() # Выводит все заголовки.
def get_first_text_block(self, email_message_instance):
maintype = email_message_instance.get_content_maintype()
if maintype == 'multipart':
for part in email_message_instance.get_payload():
if part.get_content_maintype() == 'text':
return part.get_payload()
elif maintype == 'text':
return email_message_instance.get_payload()
Расширенный поиск
Мы только что закончили с базовым поиском для всей почты в целом. Теперь мы научимся сортировать выдачу поиска на нужную и ненужную. Все доступные параметры поиска находятся в протокольной документации IMAP, так что вам определенно захочется ознакомиться с разделом SEARCH Command поближе.
Попробуем следующие способы поиска.
Поиск любых заголовков
Для поиска заголовков, так их как «Ответы», «Входящие» и т.д., используем команду (HEADER “”)
mail.uid('search', None, '(HEADER Subject "My Search Term")')
mail.uid('search', None, '(HEADER Received "localhost")')
Поиск писем, начиная с датированных вчерашним днем
Часто количество входящих сообщений слишком велико, и в IMAP не указывается способ ограничения результатов, и это делает поиск слишком медленным. Существует способ ограничить этот объем – использовать ключевое слово SENTSINCE. Формат даты SENTSINCE будет следующими: ДД-МММ-ГГГГ. В то время как Python формат будет следующем: strftime('%d-%b-%Y')
import datetime
date = (datetime.date.today() - datetime.timedelta(1)).strftime("%d-%b-%Y")
result, data = mail.uid('search', None, '(SENTSINCE {date})'.format(date=date))
Ограничение по дате, поиск по темам и исключение отправителей
date = (datetime.date.today() - datetime.timedelta(1)).strftime("%d-%b-%Y")
result, data = mail.uid('search', None, '(SENTSINCE {date} HEADER Subject "My Subject" NOT FROM "yuji@grovemade.com")'.format(date=date))
Выборка
Получаем ID переписки Gmail
Выборка может включать в себя как все тело письма, так и любое сочетание результатов выдачи, такие как отмеченные письма (просмотренные\не просмотренные). Также это касается и определенных ID в Gmail, таких как ID переписки.
result, data = mail.uid('fetch', uid, '(X-GM-THRID X-GM-MSGID)')
Получаем только ключ заголовка
result, data = mail.uid('fetch', uid, '(BODY[HEADER.FIELDS (DATE SUBJECT)]])')
Множественная выборка
Вы можете выбрать несколько писем за раз. Опытным путем я пришел к тому, что это обязательно подразумевает ввод данных через запятую.
result, data = mail.uid('fetch', '1938,2398,2487', '(X-GM-THRID X-GM-MSGID)')
Используем регулярное выражение для анализа
Полученную выдачу достаточно трудно понять, так как результат разделен парами «ключ-значение». Так что мы используем регулярное выражение для получения необходимых данных. Это достаточно просто:
import re
result, data = mail.uid('fetch', uid, '(X-GM-THRID X-GM-MSGID)')
re.search('X-GM-THRID (?P\d+) X-GM-MSGID (?P\d+)', data[0]).groupdict()
# это ваш спасательный круг, который поможет организовать большой объем полученных данных.
Подведем итоги
Поздравляем, теперь вы свободно ориентируетесь в протоколе IMAP и можете использовать Python для работы с Gmail.
- Отбор валидных мобильных номеров друзей «Вконтакте» на Python
- Строим «график счастья» на Python
- Как подружить Slack и VK с помощью Python?
- Делаем бекапы аудиозаписей плейлистов Вконтакте через Vk API и Python
- Запускаем простейший веб-сервер на Python и Flask
- 12 советов для работы с датой и временем
- Работаем с Яндекс.Метрикой на Python
А ссылку на оригинал?
(https://yuji.wordpress.com/2011/06/22/python-imaplib-imap-example-with-gmail/)
А можно забирать файлы с эл. почты? Как скачивать файлы по ссылке через python, я уже знаю.
Купить натяжной потолок в Киеве и Киевской области:Ирпень, Буча можно купить натяжной потолок