Python отправка email: полный гайд по SMTP и вложениям

Способы отправки писем

Что такое SMTP-протокол и как он отправляет электронные письма / Skillbox Media — изображение номер один

Чтобы python отправить email, используют несколько библиотек. Базовая — smtplib из стандартной библиотеки, работающая через протокол SMTP. Для работы с MIME-форматом (вложения, HTML-разметка) подключают модуль email.mime. Альтернатива — сторонние обёртки вроде yagmail или Envelopes, упрощающие синтаксис.

Выбор зависит от задачи:

  • простое текстовое сообщение — достаточно smtplib;
  • письмо с картинками и файлами — потребуется MIME;
  • массовая рассылка — лучше использовать готовые библиотеки с шаблонами.

Библиотека smtplib для отправки

Модуль smtplib входит в стандартный комплект Python, поэтому устанавливать ничего не придётся. Он реализует клиентскую часть протокола SMTP и берёт на себя весь диалог с почтовым сервером.

Базовый сценарий выглядит так:

  1. Создаётся объект SMTP с указанием хоста и порта.
  2. Вызывается starttls() для шифрования (если нужно).
  3. Происходит авторизация через login().
  4. Отправляется письмо методом sendmail().

Для проверки соединения удобно использовать локальный отладочный сервер: python -m smtpd -n -c DebuggingServer localhost:1025. Он выводит содержимое сообщений в консоль, что помогает отладить код без риска что-то отправить не туда.

Формирование письма через email.mime

Отправка email с помощью Python / Sending email with Python #shorts - YouTube - изображение номер два
Отправка email с помощью Python / Sending email with Python #shorts — YouTube — изображение номер два

Для отправки вложений и форматированного контента применяется модуль email.mime. Он позволяет собирать сообщение по частям: текст, HTML-версию, файлы. Основные классы — MIMEText для текста и MIMEBase для произвольных данных.

Сборка выглядит так:

  1. Создаётся корневой объект MIMEMultipart().
  2. В него добавляются заголовки From, To, Subject.
  3. Через метод attach() подключаются части — текст и файлы.

Для вложения файла его содержимое кодируется в Base64 и оборачивается в MIMEBase с указанием типа. Это стандартный подход, описанный в официальной документации Python.

Настройка SMTP-сервера

Для отправки писем через Python потребуется доступ к почтовому серверу, который принимает исходящие сообщения. Обычно это SMTP-хост вашего провайдера — например, для Gmail это smtp.gmail.com, для Яндекс.Почты — smtp.yandex.ru. Порт чаще всего 587 (с TLS) или 465 (с SSL).

Читать так же:  OpenGL на C: уроки для начинающих — от подключения до первых шагов

Параметры подключения удобно хранить в переменных окружения, а не в коде — так безопаснее. Учтите, что для популярных сервисов понадобится пароль приложения, а не обычный пароль от аккаунта.

Подключение к Gmail и Яндекс.Почте

Для работы с почтовыми сервисами через Python потребуется настроить доступ. У Gmail и «Яндекса» свои требования к безопасности.

  • Gmail: включите двухфакторную аутентификацию и создайте пароль приложения в настройках аккаунта.
  • Яндекс.Почта: активируйте пункт «Пароли приложений» в разделе безопасности.

После этого укажите SMTP-сервер и порт в коде — обычно это smtp.gmail.com:587 и smtp.yandex.ru:587 соответственно.

Параметры сервера и порты

Python: Send Emails From Your Raspberry Pi (no server) - RaspberryTips - изображение номер три
Python: Send Emails From Your Raspberry Pi (no server) — RaspberryTips — изображение номер три

Для отправки через SMTP обычно применяются порт 25 (устаревший, часто блокируется провайдерами), 465 (подразумевает SSL/TLS сразу) и 587 (стартует с STARTTLS). Последний считается наиболее совместимым для большинства почтовых служб. Уточняйте актуальные значения в документации вашего провайдера — у Gmail, Yandex и Mail.ru они различаются. Неверный выбор параметра приводит к ошибке соединения или таймауту.

Отправка письма с вложениями

Когда базовая пересылка сообщений освоена, логичный следующий шаг — прикрепить к письму файлы. В стандартной библиотеке для этого предусмотрен модуль email.mime, а конкретно класс MIMEMultipart. Он выступает контейнером, в который складываются и текст, и вложения.

Алгоритм действий выглядит так:

  1. Создаётся объект MIMEMultipart(), задаются тема, отправитель и получатель.
  2. Текстовая часть добавляется через MIMEText.
  3. Файл читается в бинарном режиме и оборачивается в MIMEApplication (или MIMEBase для нестандартных типов).
  4. Вложение присоединяется методом attach().

Важный нюанс: для корректной передачи кириллических имён файлов их нужно кодировать в UTF-8 через заголовок Content-Disposition. Иначе получатель увидит «кракозябры» вместо названия документа.

Ниже — минимальный рабочий пример:

import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.application import MIMEApplication

msg = MIMEMultipart()
msg['Subject'] = 'Отчёт за квартал'
msg['From'] = 'sender@example.com'
msg['To'] = 'boss@example.com'

body = MIMEText('Во вложении — сводка.', 'plain', 'utf-8')
msg.attach(body)

with open('report.pdf', 'rb') as f:
    part = MIMEApplication(f.read(), _subtype='pdf')
    part.add_header('Content-Disposition', 'attachment',
                    filename=('utf-8', '', 'отчёт.pdf'))
    msg.attach(part)

with smtplib.SMTP('smtp.example.com', 587) as server:
    server.starttls()
    server.login('sender@example.com', 'пароль')
    server.send_message(msg)

Если нужно отправить сразу несколько файлов, цикл for по списку путей решит задачу без дублирования кода. Для больших объёмов данных стоит использовать потоковую передачу, чтобы не держать весь файл в памяти.

Читать так же:  Как создать свои новости: полный гид с нуля

Обратите внимание: некоторые почтовые сервисы ограничивают размер вложения (обычно 25–50 МБ). Превышение лимита приведёт к ошибке на этапе send_message.

Добавление файлов к письму

Прикрепить вложение позволяет объект MIMEApplication или MIMEBase. Считываете файл в бинарном режиме, оборачиваете в экземпляр, задаёте заголовки Content-Disposition и Content-Type. Затем добавляете его через attach() к контейнеру MIMEMultipart. Для нескольких документов процедура повторяется циклически.

Отправка HTML-письма с изображениями

Отправка вложений по email в Python: использование smtplib - изображение номер четыре
Отправка вложений по email в Python: использование smtplib — изображение номер четыре

Для корректного отображения картинок в письме их встраивают через MIMEImage и прикрепляют к MIMEMultipart. Указывайте Content-ID для каждой вставки, тогда в HTML-разметке достаточно сослаться на cid:имя_файла. Это надёжнее, чем внешние ссылки, которые почтовые клиенты часто блокируют.

Примерный порядок действий:

  • создать контейнер MIMEMultipart;
  • добавить текстовую часть и HTML-версию;
  • прочитать изображение и обернуть его в MIMEImage;
  • присоединить файл и прописать заголовок Content-Disposition.

Такой подход гарантирует, что получатель увидит оформление даже при отключённой загрузке внешних ресурсов.

Обработка ошибок и логирование

При работе с почтовыми сервисами сбои неизбежны: от временной недоступности SMTP-сервера до неверных учётных данных. Грамотная стратегия перехвата исключений экономит часы отладки. Базовый блок try/except ловит `SMTPException` и её наследников, но для диагностики этого мало.

Практичный подход — трёхуровневая схема:

  • перехват конкретных типов ошибок (аутентификация, таймаут, квота);
  • повторная попытка отправки с экспоненциальной задержкой (например, 1с → 4с → 16с);
  • запись деталей в лог-файл с указанием времени, адресата и текста ответа сервера.

Для логирования удобен встроенный модуль `logging` — он позволяет разделять сообщения по уровням важности и выводить их одновременно в консоль и файл. Полезно фиксировать не только сам факт ошибки, но и содержимое заголовков письма — это помогает воспроизвести проблему.

Отдельного внимания заслуживает ситуация, когда письмо принято сервером, но не доставлено получателю. Тут поможет чтение возвратных сообщений (bounce-писем) через IMAP — это уже следующий уровень сложности, но именно он отличает надёжный почтовый сервис от игрушечного скрипта.

Читать так же:  Уроки Ардуино для детей: первые шаги в мир электроники

Исключения при подключении к серверу

Что такое SMTP-протокол и как он отправляет электронные письма / Skillbox Media - изображение номер пять
Что такое SMTP-протокол и как он отправляет электронные письма / Skillbox Media — изображение номер пять

При установлении соединения с SMTP-хостом часто возникают сбои. Наиболее типичные из них — ConnectionRefusedError (порт закрыт) и socket.gaierror (неверное имя хоста). Таймауты проявляются как TimeoutError, когда сервер не отвечает в отведённый срок. Для диагностики удобно использовать конструкцию try/except, перехватывая конкретные типы ошибок по отдельности. Это помогает отличить проблемы сети от неправильных учётных данных.

Проверка доставки и повторные попытки

После вызова метода отправки стоит проверить статус ответа сервера. Если код ответа не равен 250, значит, письмо не ушло. В таком случае разумно сделать несколько повторных попыток с нарастающей паузой, например, 5, 15 и 30 секунд. Это помогает справиться с временными сбоями почтового сервиса, не создавая избыточной нагрузки.

Практический пример кода

Python: Send Emails From Your Raspberry Pi (no server) - RaspberryTips - изображение номер шесть
Python: Send Emails From Your Raspberry Pi (no server) — RaspberryTips — изображение номер шесть

Соберём всё воедино. Ниже — рабочий скрипт, который отправляет письмо через SMTP-сервер Яндекса. Он включает подключение, авторизацию и передачу сообщения.

import smtplib
from email.mime.text import MIMEText

msg = MIMEText('Текст письма')
msg['Subject'] = 'Тема'
msg['From'] = 'sender@yandex.ru'
msg['To'] = 'recipient@example.com'

with smtplib.SMTP_SSL('smtp.yandex.ru', 465) as server:
    server.login('sender@yandex.ru', 'пароль')
    server.send_message(msg)

Для отправки через Gmail используйте smtp.gmail.com и порт 587 с SMTP() и starttls(). Пароль для внешних сервисов — отдельный, не основной.

Полный скрипт отправки письма

Соберите все компоненты воедино. Ниже — рабочий пример для SMTP-сервера Яндекса. Скопируйте код, подставьте свои данные и запустите.

import smtplib
from email.mime.text import MIMEText

msg = MIMEText("Текст сообщения", "plain", "utf-8")
msg["Subject"] = "Тема"
msg["From"] = "login@yandex.ru"
msg["To"] = "recipient@example.com"

with smtplib.SMTP_SSL("smtp.yandex.ru", 465) as server:
    server.login("login@yandex.ru", "пароль_приложения")
    server.send_message(msg)

Для почты Google используйте smtp.gmail.com и порт 587 с starttls(). Если нужно прикрепить файл, добавьте MIMEMultipart и MIMEBase — тогда структура письма станет составной.

Тестирование на локальном сервере

Проверить отправку писем без реального SMTP-сервера можно с помощью локального инструмента. Например, запустите python -m smtpd -c DebuggingServer -n localhost:1025 — он выведет содержимое сообщений в консоль. Для имитации почтового ящика подойдёт MailHog или Mailpit. Эти утилиты перехватывают трафик и показывают письма в веб-интерфейсе, что удобно для отладки.

Related Articles

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *