Как отправить электронное письмо с помощью Gmail в качестве поставщика с помощью Python?
Я пытаюсь отправить электронную почту (Gmail) с помощью python, но я получаю следующую ошибку.
Traceback (most recent call last):
File "emailSend.py", line 14, in <module>
server.login(username,password)
File "/usr/lib/python2.5/smtplib.py", line 554, in login
raise SMTPException("SMTP AUTH extension not supported by server.")
smtplib.SMTPException: SMTP AUTH extension not supported by server.
Python script следующий.
import smtplib
fromaddr = '[email protected]'
toaddrs = '[email protected]'
msg = 'Why,Oh why!'
username = '[email protected]'
password = 'pwd'
server = smtplib.SMTP('smtp.gmail.com:587')
server.starttls()
server.login(username,password)
server.sendmail(fromaddr, toaddrs, msg)
server.quit()
Ответы
Ответ 1
Вы должны сказать EHLO
перед тем, как просто перейти прямо в STARTTLS
:
server = smtplib.SMTP('smtp.gmail.com:587')
server.ehlo()
server.starttls()
Также вы должны действительно создавать заголовки сообщений From:
, To:
и Subject:
, отделенные от тела сообщения пустой строкой и использовать CRLF
как маркеры EOL.
например.
msg = "\r\n".join([
"From: [email protected]",
"To: [email protected]",
"Subject: Just a message",
"",
"Why, oh why"
])
Ответ 2
def send_email(user, pwd, recipient, subject, body):
import smtplib
FROM = user
TO = recipient if isinstance(recipient, list) else [recipient]
SUBJECT = subject
TEXT = body
# Prepare actual message
message = """From: %s\nTo: %s\nSubject: %s\n\n%s
""" % (FROM, ", ".join(TO), SUBJECT, TEXT)
try:
server = smtplib.SMTP("smtp.gmail.com", 587)
server.ehlo()
server.starttls()
server.login(user, pwd)
server.sendmail(FROM, TO, message)
server.close()
print 'successfully sent the mail'
except:
print "failed to send mail"
если вы хотите использовать порт 465, вам нужно создать объект SMTP_SSL
:
# SMTP_SSL Example
server_ssl = smtplib.SMTP_SSL("smtp.gmail.com", 465)
server_ssl.ehlo() # optional, called by login()
server_ssl.login(gmail_user, gmail_pwd)
# ssl server doesn't support or need tls, so don't call server_ssl.starttls()
server_ssl.sendmail(FROM, TO, message)
#server_ssl.quit()
server_ssl.close()
print 'successfully sent the mail'
Ответ 3
Я столкнулся с подобной проблемой и наткнулся на этот вопрос. Я получил ошибку аутентификации SMTP, но мое имя пользователя/пароль было правильным. Вот что исправлено. Я читал это:
https://support.google.com/accounts/answer/6010255
В двух словах google не разрешает вам входить через smtplib, поскольку он помечен таким именем входа как "менее безопасный", поэтому вам нужно перейти по этой ссылке, когда вы вошли в свою google и разрешить доступ:
https://www.google.com/settings/security/lesssecureapps
Как только это будет установлено (см. мой снимок экрана ниже), он должен работать.
![enter image description here]()
Вход в систему работает:
smtpserver = smtplib.SMTP("smtp.gmail.com", 587)
smtpserver.ehlo()
smtpserver.starttls()
smtpserver.ehlo()
smtpserver.login('[email protected]', 'me_pass')
Ответ после изменения:
(235, '2.7.0 Accepted')
Ответ до:
smtplib.SMTPAuthenticationError: (535, '5.7.8 Username and Password not accepted. Learn more at\n5.7.8 http://support.google.com/mail/bin/answer.py?answer=14257 g66sm2224117qgf.37 - gsmtp')
Все еще не работает? Если вы все еще получаете SMTPAuthenticationError, но теперь код 534, это значит, что местоположение неизвестно. Следуйте по этой ссылке:
https://accounts.google.com/DisplayUnlockCaptcha
Нажмите "Продолжить", и это даст вам 10 минут для регистрации вашего нового приложения. Итак, приступайте к другой попытке входа в систему, и она должна работать.
ОБНОВЛЕНИЕ: это, похоже, не работает сразу, вы можете застрять на некоторое время при получении этой ошибки в smptlib:
235 == 'Authentication successful'
503 == 'Error: already authenticated'
В сообщении говорится использовать браузер для входа:
SMTPAuthenticationError: (534, '5.7.9 Please log in with your web browser and then try again. Learn more at\n5.7.9 https://support.google.com/mail/bin/answer.py?answer=78754 qo11sm4014232igb.17 - gsmtp')
После включения "lesssecureapps" перейдите на кофе, вернитесь и снова попробуйте ссылку "DisplayUnlockCaptcha". Из-за пользовательского опыта может потребоваться до часа, чтобы изменение произошло. Затем повторите процедуру входа.
Ответ 4
Вы с ООП?
#!/usr/bin/env python
import smtplib
class Gmail(object):
def __init__(self, email, password):
self.email = email
self.password = password
self.server = 'smtp.gmail.com'
self.port = 587
session = smtplib.SMTP(self.server, self.port)
session.ehlo()
session.starttls()
session.ehlo
session.login(self.email, self.password)
self.session = session
def send_message(self, subject, body):
''' This must be removed '''
headers = [
"From: " + self.email,
"Subject: " + subject,
"To: " + self.email,
"MIME-Version: 1.0",
"Content-Type: text/html"]
headers = "\r\n".join(headers)
self.session.sendmail(
self.email,
self.email,
headers + "\r\n\r\n" + body)
gm = Gmail('Your Email', 'Password')
gm.send_message('Subject', 'Message')
Ответ 5
Вы можете найти его здесь: http://jayrambhia.com/blog/send-emails-using-python
smtp_host = 'smtp.gmail.com'
smtp_port = 587
server = smtplib.SMTP()
server.connect(smtp_host,smtp_port)
server.ehlo()
server.starttls()
server.login(user,passw)
fromaddr = raw_input('Send mail by the name of: ')
tolist = raw_input('To: ').split()
sub = raw_input('Subject: ')
msg = email.MIMEMultipart.MIMEMultipart()
msg['From'] = fromaddr
msg['To'] = email.Utils.COMMASPACE.join(tolist)
msg['Subject'] = sub
msg.attach(MIMEText(raw_input('Body: ')))
msg.attach(MIMEText('\nsent via python', 'plain'))
server.sendmail(user,tolist,msg.as_string())
Ответ 6
Не связано напрямую, но все же стоит отметить, что мой пакет пытается сделать отправку сообщений gmail очень быстрыми и безболезненными. Он также пытается сохранить список ошибок и пытается сразу указать на решение.
Для этого буквально нужен только этот код, чтобы сделать то, что вы написали:
import yagmail
yag = yagmail.SMTP('[email protected]')
yag.send('[email protected]', 'Why,Oh why!')
Или один лайнер:
yagmail.SMTP('[email protected]').send('[email protected]', 'Why,Oh why!')
Для пакета/установки просмотрите git или pip, доступный как для Python 2 и 3.
Ответ 7
Это работает
После этого создайте файл с именем sendgmail.py
.Затем добавьте этот код:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# =============================================================================
# Created By : Jeromie Kirchoff
# Created Date: Mon Aug 02 17:46:00 PDT 2018
# =============================================================================
# Imports
# =============================================================================
import smtplib
# =============================================================================
# SET EMAIL LOGIN REQUIREMENTS
# =============================================================================
gmail_user = '[email protected]'
gmail_app_password = 'YOUR-GOOGLE-APPLICATION-PASSWORD!!!!'
# =============================================================================
# SET THE INFO ABOUT THE SAID EMAIL
# =============================================================================
sent_from = gmail_user
sent_to = ['[email protected]', '[email protected]']
sent_subject = "Where are all my Robot Women at?"
sent_body = ("Hey, what up? friend!\n\n"
"I hope you have been well!\n"
"\n"
"Cheers,\n"
"Jay\n")
email_text = """\
From: %s
To: %s
Subject: %s
%s
""" % (sent_from, ", ".join(sent_to), sent_subject, sent_body)
# =============================================================================
# SEND EMAIL OR DIE TRYING!!!
# Details: http://www.samlogic.net/articles/smtp-commands-reference.htm
# =============================================================================
try:
server = smtplib.SMTP_SSL('smtp.gmail.com', 465)
server.ehlo()
server.login(gmail_user, gmail_app_password)
server.sendmail(sent_from, sent_to, email_text)
server.close()
print('Email sent!')
except Exception as exception:
print("Error: %s!\n\n" % exception)
Итак, если вы добьетесь успеха, увидите следующее изображение:
Я проверил, отправив электронное письмо от самого себя.
![Successful email sent.]()
Примечание. В моей учетной записи включено двухэтапное подтверждение. Пароль приложения работает с этим!
Этот параметр недоступен для учетных записей с включенной двухэтапной проверкой. Такие учетные записи требуют пароль конкретного приложения для менее безопасного доступа к приложениям.
![Less secure app access... This setting is not available for accounts with 2-Step Verification enabled.]()
Ответ 8
Теперь существует gmail API, который позволяет отправлять электронную почту, читать электронную почту и создавать проекты через REST.
В отличие от вызовов SMTP, это неблокирование, которое может быть хорошим для потоковых веб-серверов, отправляющих электронную почту в поток запросов (например, веб-серверы python). API также достаточно мощный.
- Конечно, электронная почта должна быть передана в очередь без веб-сервера, но приятно иметь параметры.
Проще всего настроить, если у вас есть права администратора Google Apps в домене, потому что тогда вы можете предоставить общее разрешение своему клиенту. В противном случае вам придется возиться с аутентификацией и разрешением OAuth.
Вот его демон, демонстрирующий это:
https://gist.github.com/timrichardson/1154e29174926e462b7a
Ответ 9
отличный ответ от @David, вот для Python 3 без общей попытки, кроме:
def send_email(user, password, recipient, subject, body):
gmail_user = user
gmail_pwd = password
FROM = user
TO = recipient if type(recipient) is list else [recipient]
SUBJECT = subject
TEXT = body
# Prepare actual message
message = """From: %s\nTo: %s\nSubject: %s\n\n%s
""" % (FROM, ", ".join(TO), SUBJECT, TEXT)
server = smtplib.SMTP("smtp.gmail.com", 587)
server.ehlo()
server.starttls()
server.login(gmail_user, gmail_pwd)
server.sendmail(FROM, TO, message)
server.close()
Ответ 10
Вот пример Gmail API. Хотя это более сложный метод, это единственный метод, который я обнаружил в 2019 году. Этот пример был взят и изменен с:
https://developers.google.com/gmail/api/guides/sending
Вам нужно будет создать проект с интерфейсами API Google через их веб-сайт. Затем вам нужно включить API GMAIL для вашего приложения. Создайте учетные данные, а затем загрузите их, сохраните как credentials.json.
import pickle
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from email.mime.text import MIMEText
import base64
#pip install --upgrade google-api-python-client google-auth-httplib2 google-auth-oauthlib
# If modifying these scopes, delete the file token.pickle.
SCOPES = ['https://www.googleapis.com/auth/gmail.readonly', 'https://www.googleapis.com/auth/gmail.send']
def create_message(sender, to, subject, msg):
message = MIMEText(msg)
message['to'] = to
message['from'] = sender
message['subject'] = subject
# Base 64 encode
b64_bytes = base64.urlsafe_b64encode(message.as_bytes())
b64_string = b64_bytes.decode()
return {'raw': b64_string}
#return {'raw': base64.urlsafe_b64encode(message.as_string())}
def send_message(service, user_id, message):
#try:
message = (service.users().messages().send(userId=user_id, body=message).execute())
print( 'Message Id: %s' % message['id'] )
return message
#except errors.HttpError, error:print( 'An error occurred: %s' % error )
def main():
"""Shows basic usage of the Gmail API.
Lists the user Gmail labels.
"""
creds = None
# The file token.pickle stores the user access and refresh tokens, and is
# created automatically when the authorization flow completes for the first
# time.
if os.path.exists('token.pickle'):
with open('token.pickle', 'rb') as token:
creds = pickle.load(token)
# If there are no (valid) credentials available, let the user log in.
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file(
'credentials.json', SCOPES)
creds = flow.run_local_server(port=0)
# Save the credentials for the next run
with open('token.pickle', 'wb') as token:
pickle.dump(creds, token)
service = build('gmail', 'v1', credentials=creds)
# Example read operation
results = service.users().labels().list(userId='me').execute()
labels = results.get('labels', [])
if not labels:
print('No labels found.')
else:
print('Labels:')
for label in labels:
print(label['name'])
# Example write
msg = create_message("[email protected]", "[email protected]", "Subject", "Msg")
send_message( service, 'me', msg)
if __name__ == '__main__':
main()
Ответ 11
Похоже на проблему старого smtplib
. В python2.7
все работает нормально.
Обновление: да, server.ehlo()
также может помочь.
Ответ 12
import smtplib
fromadd='[email protected]'
toadd='[email protected]'
msg='''hi,how r u'''
username='[email protected]'
passwd='password'
try:
server = smtplib.SMTP('smtp.gmail.com:587')
server.ehlo()
server.starttls()
server.login(username,passwd)
server.sendmail(fromadd,toadd,msg)
print("Mail Send Successfully")
server.quit()
except:
print("Error:unable to send mail")
NOTE:https://www.google.com/settings/security/lesssecureapps that should be enabled
Ответ 13
import smtplib
server = smtplib.SMTP('smtp.gmail.com', 587)
server.ehlo()
server.starttls()
server.login("fromaddress", "password")
msg = "HI!"
server.sendmail("fromaddress", "receiveraddress", msg)
server.quit()