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

Существует несколько способов отправки электронной почты с помощью Python, будь то через стороннюю библиотеку, например, с помощью boto и SES [http://stackabuse.com/how-to-send-an-email-with-boto-and- ses /] или через протокол электронной почты, например SMTP. Хотя тема использования Python для отправки электронных писем может показаться смертельной, существует так много разных способов сделать это и так много проблем, которые могут возникнуть. Я подумал, что было бы полезно написать руководство о том, как отправлять электронные письма с помощью Gmail в качестве провайдера.

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

Протокол SMTP

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

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

Следует отметить, что многие почтовые службы, такие как 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...' 

Вот и все. На самом деле это не что иное, как передача адреса сервера, порта и вызова .helo() , который идентифицирует вас на 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), хотя вы можете просто не smtplib параметр порта, и 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, в котором выдается отзывный токен, поэтому они должны найти другой способ гарантировать, что неавторизованные стороны не получат доступ к вашим данным.

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

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

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

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

Войдите, используя пароли приложений

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

Отображение разблокировки Captcha

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

Что касается фактического кода 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.

Используя строку электронной почты, которую мы server , вам необходимо вызвать метод .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? Для каких приложений вы его используете? Дайте нам знать об этом в комментариях!

Ресурсы

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

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

comments powered by Disqus