Эта проблема
Недавно я получил запрос от моего клиента. Он попросил, чтобы я пишу скрипт, который подключается к определенному почтовому ящику, проверьте, есть ли новые электронные письма, прочитайте их и загружают вложения и выполняют некоторые данные анализа данных на этих вложениях. Я был супер взволнован этой задачей, и я спросил себя; Можно ли читать электронные письма с помощью Python?
Решение
Я начал гугла, и мне повезло найти, что можно читать электронные письма с помощью Python.
В этом сообщении я объясню, как мне удалось прочитать электронные письма с почтового сервера IMAP и как я загрузил вложения и сохранил их в определенную папку.
Если вы знакомы с Python, этот учебник для вас. Чтобы завершить этот учебник, вам необходимо установить Python 3.6 в вашем ноутбуке и установленной виртуальной среде.
Первые вещи сначала; Создайте проект и инициализируйте свою виртуальную среду
Создать проект, который мы будем использовать: Перейти к вашей командной строке и введите следующие строки кода:
mkdir read_emails_project & cd read_emails_project
Оказавшись в проекте, давайте инициализируем Git:
git init.
Как только мы инициализировали GIT, давайте создадим виртуальную среду:
virtualenv -p python .venv
Вы можете активировать виртуальную среду со следующей строкой кода:
Источник .VENV/BIN/ACTIVATE
Это не должно использовать виртуальную среду. Вы можете использовать ваш предпочтительный менеджер окружающей среды; Я просто предпочитаю использовать виртуальные среды.
После завершения установки мы можем начать с захватывающей части проекта.
Никогда не пишите секретные учетные данные в код, используйте переменные среды
Поскольку мы читаем электронные письма с папки «Входящие», нам понадобятся учетные данные электронной почты. Откуда мы читаем эти полномочия? Одна вещь наверняка; Мы не ставим их в код, это плохая практика !!! Сообщество разработчиков может наказать вас за написание учетных данных или секретного кода непосредственно в кодовую базу. Мы будем использовать .env
Файл, содержание которого будет известно только нам, и мы никогда не будем делиться ним с кем-либо в Интернете, даже вкладывая его в личный репозиторий Git.
Давайте создадим .env
файл
прикоснуться .env.
И создайте файл Gitignore, чтобы сказать Git, которые файлы игнорируют.
Touch .Gitignore
Откройте .gitignore и добавьте следующие строки, чтобы игнорировать .env
файл:
.venv env
В этих линиях мы инструктируем Git игнорировать наши .env
файлы и наша виртуальная среда.
Теперь мы можем заполнить .env
Файл с нашими учетными данными:
USER_EMAIL='your@email.com' USER_PASSWORD='your secret password.'
Мы записали наши учетные данные электронной почты в .env
файл; Давайте теперь напишем метод, который читает их оттуда. Для этой задачи мы будем использовать пакет Python под названием Python-dotenv.
Давайте установим его с помощью:
PIP устанавливает -U Python-dotenv
Напишем функцию, которая читает и возвращает эти переменные среды:
Вы можете создать файл с именем Utils.py
и добавьте следующие строки кода:
import os from dotenv import load_dotenv def read_credentails(): """ Return user's credentials from the environment variables file and raise a an exception if the credentials are not present Raises: NotImplementedError: [description] """ load_dotenv() USER_EMAIL = os.getenv("USER_EMAIL") USER_PASSWORD = os.getenv("USER_PASSWORD") if USER_EMAIL and USER_PASSWORD: return USER_EMAIL, USER_PASSWORD else: raise ValueError('Please add a .env file and write the credentials it it , refer to the sample')
Из этой функции вы можете заметить, что мы используем load_env
Функция, она загружает переменные среды из нашего .env
Файл и открывает их в системные переменные среды, чтобы мы могли читать их оттуда. После прочтения переменных среды функция возвращает их в виде кортежа.
В следующем разделе мы собираемся выполнить самую интересную часть этого учебника; Это включает в себя чтение электронных писем и загрузку вложений.
Чтение электронных писем:
Я был рад найти, что у Python есть встроенная функция, которая позволяет нам подключиться к почтовому ящику. Это в imaplib
модуль. Он также имеет модуль для анализа электронных писем.
Давайте создадим файл read_emails_scripts.py
внутри него; Мы будем выполнять всю магию, нам нужно.
Давайте импортируем модули:
from email import message_from_bytes from imaplib import IMAP4_SSL from .utils import read_credentails
Мы импортируем:
- message_from_bytes Функция из модуля электронной почты. Это поможет нам прочитать электронные письма, которые приходят как байты и преобразуют их в текст.
- IMAP4_SSL: класс, который является основным классом, который поможет нам выполнить все операции. Обратите внимание, что мы используем протокол IMAP4 для чтения электронных писем, IMAP4 – это почтовый протокол, используемый для доступа к почтовому ящику на удаленном сервере от локального клиента электронной почты. IMAP может быть более сложным, но обеспечивает больше удобств для синхронизации на нескольких устройствах. Вы можете узнать больше о протоколе электронной почты здесь
- Наша функция read_credentials, которую мы представили в предыдущем разделе.
Я создал функцию, которая выполняет операцию и возвращает генератор со всеми письмами, найденными в почтовом ящике, вот оно:
def get_unseen_emails(email_address, password): """ Filter the email and return unseen emails Args: email_address (string): recipient email password (password): recipient password """ with IMAP4_SSL("your_imap_server") as mail_connection: mail_connection.login(email_address, password) mail_connection.list() mail_connection.select('INBOX') (retcode, messages) = mail_connection.search(None, '(OR (UNSEEN) (FROM your.email@gmail.com))') if retcode == 'OK' and messages[0]: for index, num in enumerate(messages[0].split()): typ, data = mail_connection.fetch(num, '(RFC822)') message = message_from_bytes(data[0][1]) typ, data = mail_connection.store(num, '+FLAGS', '\\Seen') yield message
Вы можете видеть, что мы создаем безопасную Mail_connection от класса IMAP4SSL и используя его с помощью менеджера контекста Python. Мы будем использовать объект mail_connection для выполнения всех операций, которые мы хотим для нашего почтового ящика.
После создания инстанции мы входим в почтовый ящик с нашими учетными данными, затем перечислите все категории почтовых ящиков, которые у нас есть, например, В Google у нас есть почтовый ящик, спам, обновления, форумы, спам, мы выбираем только папку входящей коробки, а из папки «Входящие» выписываем только невидимые сообщения или электронные письма, исходящие с вашего адреса электронной почты. Обратите внимание, что вы можете искать что-нибудь в вашем почтовом ящике и даже сложные запросы.
Поиск возвращает RetCodes с сообщениями и их IDSnote, что:
Сервер присвоил идентификатор сообщения на электронные письма и зависит от реализации. Протокол IMAP4> дает различие между последовательными идентификаторами для сообщений в данной точке во времени> во время транзакции и идентификаторов UID для сообщений, но не все серверы, кажется, беспокоятся.
Как только у нас есть идентификаторы сообщений, мы можем получить идентификаторы и формат заголовков, которые мы хотим. Мы используем RFC822, чтобы получить все сообщение в виде отформатированного сообщения RFC 2822. RFC 2822 – это протокол для стандартных сообщений, отправленных между компьютерами; Вы можете прочитать больше об этом здесь
В следующей строке мы используем функцию message_from_bytes из модуля электронной почты для преобразования байтов, которые мы получили в качестве сообщения.
Затем мы отмечаем сообщение о том, как видно, используя метод магазина, и мы даем результаты. Это означает, что функция вернет итератор, который является объектом, который мы можем повторить. Найти больше о итераторах и генераторах в Python здесь и здесь Отказ
Как только мы получили электронные письма, давайте создадим функцию, которая получает вложения от этого электронного письма.
Получение вложения от электронной почты:
def get_mail_attachments(message, condition_check): """ Get attachments files from mail Args: message (email ): email object to retrieve attachment from condition_check ([function]): the function to use when filtering the email should return specific condition we are filtering Returns: [filename, file]: the file name, input stream from the files """ for part in message.walk(): if part.get_content_maintype() == 'multipart': continue if not part.get('Content-Disposition'): continue file_name = part.get_filename() if condition_check(file_name): yield part.get_filename(), part.get_payload(decode=1)
Эта функция принимает объект электронной почты, данный последней функцией и функцией фильтра, которая сообщает, какое расширение мы можем фильтровать от электронной почты, итерации по всей его части, используя метод Walk (). Для каждой части мы проверяем, если основной тип не мультипартатован, а содержание-нём не является
Если ни один из этих условий не удовлетворен, мы получаем имя файла и дайте поток байта из электронной почты, а также имя файла.
Положить все вместе:
Теперь у нас есть все строительные блоки приложения. Давайте поставим их в основную функцию:
Создайте файл под названием Run.py
и добавить следующий код внутри:
from utils import read_credentails from reading_emails_scripts import get_mail_attachments, get_unseen_emails if __name__ == "__main__": email_address, password = read_credentails() messages = get_unseen_emails(email_address, password) if messages: for message in messages: attachments = get_mail_attachments(message, lambda x: x.endswith('.xml')) for attachment in attachments: if attachment: with open('./data/xml_files/{}'.format(attachment[0]), 'wb') as file: file.write(attachment[1])
Мы видим, что; Мы звоним Read_credentials, которые возвращают учетные данные из файла .env, мы вызываем метод get_unseen_emails, который возвращает наши сообщения, мы проверяем, есть ли в приложении с функцией get_mail_atchment и если есть вложение, мы сохраняем его к папке нашего выбора.
Заключение
В этом руководстве мы проходили весь процесс чтения электронных пищевых питонов, мы увидели, как загружать вложения из электронной почты, и мы все вместе вкладываем, чтобы иметь полностью рабочий скрипт.
Это также хорошая практика для записи модульных тестов для проверки кода, который вы пишете, потому что я считаю, что что-то не тестировано, нарушено.
В следующей части мы увидим, как вы можете написать тесты подразделения для этого куска кода. Так что оставайтесь настроенными для большего количества.
Вы можете проверить код для этого урока от этого Репозиторий GitHub Отказ
Ваше здоровье!
Использованная литература:
- Python модуль недели имаплиб
- Читайте электронные письма и загрузите вложения
- Читать только новые электронные письма в Python на Stackoverflow
Оригинал: “https://dev.to/espoir/reading-emails-from-a-mailbox-with-python-1389”