Отправка электронных писем из Python

| Python

Многим приложениям необходимо взаимодействовать с пользователями с помощью электронных средств. Электронная почта является одним из самых распространённым и дешёвым методом. Её применяют для сброса забытого пароля, рекламы, подтверждения заказа или активации учётных записей пользователей. Независимо от используемого языка программирования, процесс отправки электронной почты всегда один и тот же.

Основы электронной почты

При отправке сообщения электронной почты из веб-приложения или локального программного обеспечения, клиентское приложение упаковывает сообщение и отправляет его с помощью SMTP (Simple Mail Transfer Protocol) сервера.

Данный сервер используется для отправки электронной почты, независимо от используемого почтового клиента, такого как Outlook, Thunderbird или Python программы. Когда создаётся учётная запись в любой почтовой хостинговой компании, предоставляется учётные данные SMTP для отправки электронной почты с помощью своих серверов.

SMTP сервер не всегда является внешним сервером. В некоторых случаях отправка электронной почты производится с того же компьютера, на котором запущен Python скрипт. В данном случае используется localhost в качестве SMTP сервера. Чтобы узнать параметры конфигурации, ознакомьтесь с документацией поставщика услуг электронной почты. В данной статье будет использоваться сервис Gmail. Для начала нужно собрать параметры электронной почты. Их можно затребовать от пользователя из входного потока, либо жёстко закодированных в коде.

Для отправки электронки требуются следующие реквизиты:

  • Адрес получателя
  • Адрес отправителя
  • Тема сообщения
  • Тело сообщения
  • Вложения (если таковые имеются, оно не обязательно)
  • Адрес SMTP сервера

Обычно для подключение по SMTP используется 25 TCP порт, но также может быть 2525 и 587. Можете использовать любой адрес электронной почты отправителя, но некоторые принимающие серверы, например Gmail, обнаруживают поддельные адреса отправителя и могут поместить электронную почту в папку с спамом.

Поэтому лучше использовать «реальный» адрес электронной почты, который на самом деле существует.

Отправка электронной почты с помощью модуля smtplib

Первый шагом будет импорт встроенной в Python библиотеки smtplib. Данная библиотека выполняет большую часть кода в своих внутренних методах и свойствах, поэтому не потребуется писать много кода для отправки электронной почты.

Введите следующий код в начале файла:

import smtplib

Перед рассылкой писем нужно настроить параметры электронной почты, например, определим их в виде переменных:

import smtplib

sender = "[email protected]"
recipient = "[email protected]"
subject = "Тестовое письмо из Python"
text = "Привет, Мир!"

Включение SMTP доступа в Gmail

Чтобы разрешить приложению Python входить на серверы Gmail с помощью учетной записи для отправки сообщений электронной почты, необходимо разрешить это в настройках учетной записи. Перейдите по ссылке https://myaccount.google.com/intro/security предварительно залогинившись под своей в учетной записью и включив эту функцию.

Если вы забудете включить доступ, то получите исключение SMTPAuthenticationError.

SMTP сервер Gmail находится по адресу smtp.gmail.com и использует TCP порт 587. Имя пользователя – это ваш адрес электронной почты, а пароль – пароль к электронной почте. Давайте добавим еще одну переменную для хранения пароля, так как у нас уже есть имя пользователя в переменной «sender».

import smtplib

sender = "[email protected]"
recipient = "[email protected]"
password = "thepassword" # Ваш SMTP пароль для Gmail
subject = "Тестовое письмо из Python"
text = "Hello from Python"

Обратите внимание, что переменная text содержит только одно предложение. Если нужен многострочный текст, то можно использовать символ \n для добавления новых строк текста:

text = "Hello from Python\nThis is line 2\nAnd line 3"

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

Поскольку конфиденциальность является важным условием, воспользуемся классом SMTP_SSL, чтобы обеспечить защиту взаимодействия программы Python и SMTP сервером.

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

import smtplib

sender = "[email protected]"
recipient = "[email protected]"
password = "xxxxxx" # SMTP пароль для Gmail
subject = "Тестовое письмо из Python"
text = "Hello from Python"

smtp_server = smtplib.SMTP_SSL("smtp.gmail.com", 465)
smtp_server.login(sender, password)
message = "Subject: {}\n\n{}".format(subject, text)
smtp_server.sendmail(sender, recipient, message)
smtp_server.close()

Во-первых, метод SMTP_SSL устанавливает параметры подключения к серверу с помощью SSL. Затем метод login() проверяет имя пользователя и пароль. Если они будут ошибочны, то будет вызвано исключение:

smtplib.SMTPAuthenticationError: (535, b'5.7.8 Username and Password not accepted. Learn more at\n5.7.8  https://support.google.com/mail/?p=BadCredentials o22 sm62348871wrb.40 - gsmtp')

Кроме того, если воспользоваться неправильным именем пользователя и паролем в сервисе Gmail, будет отправлено уведомление о неудачной попытке входа. Если используется Gmail, для практики работы с электронной почты с Python, старайтесь избегать слишком частых неправильных попыток входа в систему, иначе Google заблокирует учетную запись в целях безопасности. Лучше использовать тестовую учётную запись для экспериментов.

Затем метод sendmail() сообщает SMTP серверу о отправке данных электронной почты. Обратите внимание, что метод не принимает отдельными аргументами тему и текст сообщения. Вместо этого формируется служебная строковая переменная message с префиксом «Subject:» в тексте сообщения. В которой через символы \n\n скомпонованы subject и text.

Если возникает проблема с именем пользователя и паролем или сбой вызова login(), может возникнуть исключение SMTPSenderRefused:

smtplib.SMTPSenderRefused: (530, b'5.5.1 Authentication Required. Learn more at\n5.5.1  https://support.google.com/mail/?p=WantAuthError o22sm62348871wrb.40 - gsmtp', '[email protected]')

Примечание. Для разрешения отправки Гуглом отправлять электронные письма перейдем на сайт настройки безопасности приложений и активируем переключатель "Небезопасные приложения разрешены".

Если все пойдет хорошо, и запустить код с своими параметрами учётной записи, сообщение электронной почты будет доставлено на адрес получателя.

Вы можете отправить несколько писем аналогичным образом, просто повторно вызвав метод sendmail(). После завершения отправки необходимо закрыть SMTP-подключение, вызвав метод close() для объекта SMTP_SSL.

Это все, что нужно, чтобы отправить письмо из Python.

Просто не забудьте ограничить количество писем, отправляемых в течении суток, иначе можно столкнуться со спам-фильтрами. Сервис Gmail ограничивает количество сообщений, которые можно отправить одномоментно, так что можно поместить задержку между отправкой, например, с помощью функции time.sleep().

См. также перевод документации по модулю smtplib на русском языке.