Эйчары большие любители устраивать регулярное ревью позиции, как они это объясняют «в корреляции с твоими целями». Представь их удивление, когда ты скажешь, что теперь твоя цель — написать почтовый скрипт для отправки почты на Python
Для отправки электронной почты используется протокол SMTP. Python в данном случае — не панацея. Поднять почтовый сервер можно и на node.js, а чтобы не пропустить все лайфхаки по программированию на фрейморках рекомендуем занести в закладки блог Babacoding.
Матчасть
Электронную почту в Python можно отправлять двумя способами: поднять собственный SMTP-сервер (с помощью модуля smtpd), либо написать скрипт с помощью библиотеки smtplib, являющейся клиентом этого протокола
Во втором случае для отправки нам нужно подключиться к какому-либо SMTP-серверу, например smtp.yandex.ru, поэтому для примера мы возьмем свой электронный ящик на Яндексе, но можно использовать абсолютно любую, даже доменную почту.
Если вдруг у вас нет библиотеки smtplib, её можно установить через менеджер пакетов PIP, командой C:\Python>python -m pip install smtplib через CMD (переместитесь с помощью команды CD в каталог, где у вас установлен Python)
Подключение
Подключаться к серверу мы будем через конструктор класса SMTP — именно он инкапсулирует SMTP-соединение
class smtplib.SMTP(host=», port=0, local_hostname=None, [timeout, ]source_address=None)
- Host — указывается IP-адрес или домен SMTP-сервера
- Port — указывается порт подключения. Тут всё зависит от того, используется ли на сервере шифрование. Как правило, порт без шифрования — 25, с TLS — 587, c SSL — 465)
- Local_hostname — если SMTP-сервер расположен на локальном ПК, то необходимо указать localhost.
- Source_address — необязательный параметр, который позволяет выполнять привязку к определенному исходному адресу на машине с несколькими сетевыми интерфейсами и/или к определенному исходному TCP-порту
Отправка
Отправка самого сообщения происходит за счет метода SMTP.sendmail —
SMTP.sendmail(from_addr, to_addrs, msg, mail_options=(), rcpt_options=())
- From_addr — адрес отправителя.
- To_addrs — адрес получателя
- Msg — отправляемое сообщение (формат этого параметра должен быть строкой)
Настройка ящика
Так как мы тестируем отправку через ящик Яндекса, перед тем как начать необходимо проверить настройки — скрипт работает как обычный почтовый клиент.
Первым делом, необходимо проверить, включен ли в ящике IMAP (без него SMTP работать не будет по соображениям безопасности)

Если у вас активны пароли приложений — не забудьте получить дополнительный пароль для своего скрипта:


Пишем код
Импортируем нужные для работы библиотеки:
import smtplib from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText
Далее создаём сообщение с помощью класса MIMEMultipart — нужно указать все заголовки (части) составного сообщения. MIMEText предназначен для текста (например, text/plain или text/html), если все сообщение находится в текстовом формате или его часть.
msg = MIMEMultipart() msg['From'] = '****@yandex.ru' msg['To'] = '****@gmail.com' msg['Subject'] = 'Тест скрипта SMTP' message = 'Это тестовое сообщение и отвечать на него не нужно' msg.attach(MIMEText(message))
Если нужно написать сообщение в несколько строк используйте символ переноса строки \n
message = ‘Это тестовое сообщение и отвечать на него не нужно \n Но если очень хочется, то можно’
Создаём экземпляр (объект) класса SMTP. Обратите внимание на строчку mailserver.set_debuglevel(True) — так мы включаем режим отладки, чтобы в случае проблем можно было посмотреть логи
mailserver = smtplib.SMTP('smtp.yandex.ru',587)
mailserver.set_debuglevel(True)
Дальше нам нужно инициировать рукопожатие TLS. Отправляем команду ehlo() — сервер должен ответить на него. Затем запускаем сам протокол. После запуска вы должны снова вызвать ehlo() перед аутентификацией.
# Определяем, поддерживает ли сервер TLS
mailserver.ehlo()
# Защищаем соединение с помощью шифрования tls
mailserver.starttls()
# Повторно идентифицируем себя как зашифрованное соединение перед аутентификацией.
mailserver.ehlo()
Подключаемся к серверу, отправляем письмо. Используем as_string (), чтобы превратить MIMEText в строку
mailserver.login('*****@yandex.ru', 'здесь_пароль')
mailserver.sendmail('*****@yandex.ru','****@gmail.com',msg.as_string())
Финальный вариант кода. В нём мы добавили простую обработку исключений (try/except) для удобства вывода
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
msg = MIMEMultipart()
msg['From'] = '******@yandex.ru'
msg['To'] = '*****@gmail.com'
msg['Subject'] = 'Тест скрипта SMTP'
message = 'Это тестовое сообщение и отвечать на него не нужно'
msg.attach(MIMEText(message))
try:
mailserver = smtplib.SMTP('smtp.yandex.ru',587)
mailserver.set_debuglevel(True)
# Определяем, поддерживает ли сервер TLS
mailserver.ehlo()
# Защищаем соединение с помощью шифрования tls
mailserver.starttls()
# Повторно идентифицируем себя как зашифрованное соединение перед аутентификацией.
mailserver.ehlo()
mailserver.login('******@yandex.ru', 'здесь_пароль')
mailserver.sendmail('******@yandex.ru','******@gmail.com',msg.as_string())
mailserver.quit()
print("Письмо успешно отправлено")
except smtplib.SMTPException:
print("Ошибка: Невозможно отправить сообщение")
Результат:

Письмо успешно дошло адресату:

Для отправки нескольким получателям добавьте конструкцию
recipients = [‘1@mail.com’, ‘2@mail.com’]
msg[‘To’] = «, «.join(recipients)
В строчке mailserver.sendmail исправьте код
mailserver.sendmail (*****@yandex.ru, recipients, msg.as_string())
Вариант для SSL
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
msg = MIMEMultipart()
msg['From'] = '*******@yandex.ru'
msg['To'] = '******@gmail.com'
msg['Subject'] = 'Тест скрипта SMTP'
message = 'Это тестовое сообщение и отвечать на него не нужно'
msg.attach(MIMEText(message))
try:
mailserver = smtplib.SMTP_SSL('smtp.yandex.ru',465)
mailserver.set_debuglevel(True)
mailserver.login('*****@yandex.ru', 'здесь_пароль')
mailserver.sendmail('*****@yandex.ru','******@gmail.com',msg.as_string())
mailserver.quit()
print("Письмо успешно отправлено")
except smtplib.SMTPException:
print("Ошибка: Невозможно отправить сообщение")
Результат:

