Рубрики
Без рубрики

Чтение электронных писем из почтового ящика с Python

Эта проблема Недавно я получил запрос от моего клиента. Он просил, чтобы я пишу SC … Теги с Python, Emails.

Эта проблема

Недавно я получил запрос от моего клиента. Он попросил, чтобы я пишу скрипт, который подключается к определенному почтовому ящику, проверьте, есть ли новые электронные письма, прочитайте их и загружают вложения и выполняют некоторые данные анализа данных на этих вложениях. Я был супер взволнован этой задачей, и я спросил себя; Можно ли читать электронные письма с помощью 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 Отказ

Ваше здоровье!

Использованная литература:

Оригинал: “https://dev.to/espoir/reading-emails-from-a-mailbox-with-python-1389”