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

Как отправлять электронные письма с помощью Gmail с помощью Python

Автор оригинала: Scott Robinson.

Как отправлять электронные письма с помощью Gmail с помощью Python

Существует довольно много способов отправки электронной почты с помощью Python, будь то через стороннюю библиотеку , такую как boston и SES, или через протокол электронной почты, такой как SMTP. В то время как тема использования Python для отправки электронных писем может показаться, что это было сделано до смерти, существует так много различных способов сделать это и так много проблем, которые могут возникнуть. Я подумал, что было бы полезно написать учебник о том, как отправлять электронные письма с Gmail в качестве поставщика с помощью Python.

Протокол SMTP

Это не может быть сюрпризом, но, конечно, Python уже имеет библиотеку, которая позволяет вам подключаться к серверу SMTP , как тот, который использует Gmail. Эта библиотека называется, как и следовало ожидать, smtplib и поставляется в комплекте с Python.

SMTP (Simple Mail Transfer Protocol)-это протокол прикладного уровня (поверх TCP), используемый для связи с почтовыми серверами из внешних служб, таких как почтовый клиент на вашем телефоне. SMTP-это только протокол доставки, поэтому вы не можете получить электронную почту с его помощью, вы можете только отправить электронную почту, на чем мы и сосредоточимся в этой статье. Если вы хотите получить электронную почту вместо этого, то вам нужно проверить протокол IMAP (Internet Message Access Protocol).

Я должен отметить, что многие почтовые службы , такие как Gmail , обычно не используют SMTP на своих внутренних почтовых серверах. SMTP обычно просто предоставляется в качестве внешнего интерфейса для их службы через smtp.gmail.com сервер. Это в основном предназначено для использования почтовыми клиентами на вашем телефоне или компьютере (например, Outlook, Thunderbird и т. Д.).

Открытие соединения

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

Используя эту библиотеку, вы можете создать соединение с почтовым сервером несколькими различными способами. В этом разделе мы сосредоточимся на создании простого, небезопасного соединения (которое должно редко, если вообще когда-либо, использоваться). Это соединение не зашифровано и по умолчанию используется порт 25. Однако протокол отправки почты на самом деле использует 587, что мы и будем использовать.

Эти соединения очень просто создать с помощью smtplib . Незашифрованная версия может быть создана с помощью:

import smtplib

try:
    server = smtplib.SMTP('smtp.gmail.com', 587)
    server.ehlo()
except:
    print 'Something went wrong...'

И это все. На самом деле это не намного больше, чем передача адреса сервера, порта и вызов .hello() , который идентифицирует вас на SMTP-сервере. Используя этот объект server , теперь вы можете отправлять электронную почту по небезопасному соединению.

Примечание: Возможно, вы еще не готовы отправлять электронные письма. Gmail накладывает некоторые ограничения на SMTP – соединения, подобные этому. См. Раздел “Аутентификация с помощью Gmail” ниже для получения дополнительной информации.

Использование защищенного соединения

Когда SMTP-соединение защищено через TLS/SSL, оно выполняется через порт 465 и обычно называется SMTPS. Излишне говорить, что вы должны всегда использовать защищенное соединение .

Существует несколько различных способов защиты SMTP-соединений в библиотеке smtplib . Первый способ-сначала создать небезопасное соединение, а затем перейти на TLS. Это делается с помощью метода .starttls () .

import smtplib

try:
    server = smtplib.SMTP('smtp.gmail.com', 587)
    server.ehlo()
    server.starttls()
    # ...send emails
except:
    print 'Something went wrong...'

Обратите внимание, что хотя это очень похоже на предыдущее небезопасное соединение, которое мы создали, все, что отличается, – это то, что мы используем метод .starttls() для обновления соединения до безопасного.

Другой вариант-создать SSL-соединение с самого начала. В этом случае вместо этого вы захотите использовать метод .SMTP_SSL() :

import smtplib

try:
    server_ssl = smtplib.SMTP_SSL('smtp.gmail.com', 465)
    server_ssl.ehlo()   # optional
    # ...send emails
except:
    print 'Something went wrong...'

Среди других незначительных отличий мы сразу же используем порт SMTPS (465), хотя вы можете просто оставить параметр port вне этого значения, и smtplib все равно будет иметь значение по умолчанию 465.

Теперь, когда у нас есть связь, давайте создадим электронную почту.

Создание электронной почты

Электронные письма по своей сути-это просто строки текста, соединенные символами новой строки. Большинство писем, по крайней мере, будут иметь поля “От”, “До”, “Тема” и “Тело”. Вот простой пример:

From: [email protected]
To: [email protected], [email protected]
Subject: OMG Super Important Message

Hey, what's up?

- You

Как видите, каждая строка содержит новое поле со своими данными. Ни двоичного протокола, ни XML, ни JSON, только строки, разделенные строками.

Простой способ параметризации этих полей – использовать форматирование строк в Python:

sent_from = '[email protected]'
to = ['[email protected]', '[email protected]']
subject = 'OMG Super Important Message'
body = 'Hey, what's up?\n\n- You'

email_text = """\
From: %s
To: %s
Subject: %s

%s
""" % (sent_from, ", ".join(to), subject, body)

Теперь все , что вам нужно сделать, это передать строку email_text в smtplib , которую мы покажем в следующем разделе, и вы можете идти.

Аутентификация с помощью Gmail

Есть несколько шагов, которые вам нужно сделать, прежде чем вы сможете отправлять электронные письма через Gmail с помощью SMTP, и это связано с аутентификацией. Если вы используете Gmail в качестве провайдера, вам нужно будет сказать Google, чтобы он разрешил вам подключаться через SMTP, который считается “менее безопасным” методом.

Вы действительно не можете винить Google за то, что он настроил его таким образом, так как ваше приложение (или какое-то другое стороннее приложение) должно будет иметь ваш пароль для жалобного текста, чтобы это работало, что определенно не идеально. Это не похоже на протокол OAuth, где выдается отзываемый токен, поэтому они должны найти другой способ гарантировать, что никакие несанкционированные стороны не получат доступа к вашим данным.

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

Во-первых, вы захотите разрешить менее защищенным приложениям доступ к вашей учетной записи. Для получения подробных инструкций о том, как это сделать, вы должны проверить эту страницу:

Разрешение менее защищенным приложениям получать доступ к вашей учетной записи

Если в вашей учетной записи включена 2-ступенчатая проверка, вам нужно будет создать пароль для конкретного приложения для менее безопасных приложений, подобных этому. В этом случае вам нужно будет следовать приведенным здесь инструкциям:

Войдите в систему с помощью паролей приложений

И наконец, если вы все еще получаете SMTPAuthenticationError с кодом ошибки 534, то вам нужно будет сделать еще один шаг, чтобы это сработало.

Display Unlock Captcha

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

Что касается фактического кода Python, то все, что вам нужно сделать, это вызвать метод login :

import smtplib

gmail_user = '[email protected]'
gmail_password = '[email protected]!'

try:
    server = smtplib.SMTP_SSL('smtp.gmail.com', 465)
    server.ehlo()
    server.login(gmail_user, gmail_password)
except:
    print 'Something went wrong...'

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

Теперь, когда вы настроили SMTP-соединение и авторизовали свое приложение с помощью Google, вы, наконец, можете использовать Python для отправки электронной почты с помощью Gmail.

Используя строку электронной почты, которую мы построили выше, и подключенный/аутентифицированный сервер объект, вам нужно вызвать метод .sendmail () . Вот полный код, включая методы закрытия соединения:

import smtplib

gmail_user = '[email protected]'
gmail_password = '[email protected]!'

sent_from = gmail_user
to = ['[email protected]', '[email protected]']
subject = 'OMG Super Important Message'
body = 'Hey, what's up?\n\n- You'

email_text = """\
From: %s
To: %s
Subject: %s

%s
""" % (sent_from, ", ".join(to), subject, body)

try:
    server = smtplib.SMTP_SSL('smtp.gmail.com', 465)
    server.ehlo()
    server.login(gmail_user, gmail_password)
    server.sendmail(sent_from, to, email_text)
    server.close()

    print 'Email sent!'
except:
    print 'Something went wrong...'

Вывод

Помимо специфичных для Gmail шагов авторизации (включая менее безопасные приложения и т. Д.), этот код должен работать практически для любого другого поставщика электронной почты, поддерживающего SMTP-доступ, При условии, что у вас есть правильный адрес сервера и порт. Если вы обнаружите, что другие провайдеры вводят специальные ограничения на доступ SMTP, как это делает Google, сообщите нам об этом! Мы хотели бы включить сюда как можно больше информации.

Вы программно отправляете электронные письма с помощью SMTP? Для каких приложений вы его используете? Дайте нам знать в комментариях!

Ресурсы

Edit : Спасибо crop (в комментариях) за то, что вы указали, что Gmail накладывает ряд ограничений на людей, отправляющих электронную почту с помощью SMTP. Бесплатные аккаунты ограничены 500 электронными письмами в день и ограничиваются примерно 20 электронными письмами в секунду.

Если вы считаете, что превысите эти ограничения, то можете либо настроить свой собственный SMTP-сервер, либо воспользоваться такими сервисами, как AWS SES или Sendgrid.