Эйчары большие любители устраивать регулярное ревью позиции, как они это объясняют «в корреляции с твоими целями». Представь их удивление, когда ты скажешь, что теперь твоя цель — написать почтовый скрипт для отправки почты на 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("Ошибка: Невозможно отправить сообщение")
Результат: