如何使用Python以Gmail作为提供者发送电子邮件?

我试图使用python发送电子邮件(Gmail),但我得到以下错误。

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脚本如下所示。

import smtplib
fromaddr = 'user_me@gmail.com'
toaddrs  = 'user_you@gmail.com'
msg = 'Why,Oh why!'
username = 'user_me@gmail.com'
password = 'pwd'
server = smtplib.SMTP('smtp.gmail.com:587')
server.starttls()
server.login(username,password)
server.sendmail(fromaddr, toaddrs, msg)
server.quit()
411497 次浏览

你需要在直接运行到STARTTLS之前说EHLO:

server = smtplib.SMTP('smtp.gmail.com:587')
server.ehlo()
server.starttls()

此外,你还应该创建From:To:Subject:消息头,用空行与消息体分开,并使用CRLF作为EOL标记。

如。

msg = "\r\n".join([
"From: user_me@gmail.com",
"To: user_you@gmail.com",
"Subject: Just a message",
"",
"Why, oh why"
])

注意:

为了让这个工作,你需要启用“允许不安全的应用程序”;选项在您的gmail帐户配置。否则,您将收到“严重安全警报”;当gmail检测到一个非谷歌应用程序试图登录你的帐户。

似乎是老smtplib的问题。在python2.7中一切工作正常。

更新:是的,server.ehlo()也可以帮助。

你可以在这里找到它: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())
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"

如果你想使用Port 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'

你同意OOP吗?

#!/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')
现在有一个gmail API,它可以让你通过REST发送电子邮件,阅读电子邮件和创建草稿。 与SMTP调用不同,它是非阻塞的,这对于在请求线程中发送电子邮件的基于线程的web服务器(如python web服务器)来说是一件好事。这个API也非常强大。< / p >
  • 当然,电子邮件应该交给一个非web服务器队列,但有选择是很好的。

如果您在域上拥有谷歌应用程序管理员权限,则最容易设置,因为这样您就可以向您的客户端授予全面权限。否则,您必须摆弄OAuth身份验证和权限。

下面是一个要点:

https://gist.github.com/timrichardson/1154e29174926e462b7a

我遇到过类似的问题,并无意中发现了这个问题。我得到一个SMTP身份验证错误,但我的用户名/ pass是正确的。下面是解决问题的方法。我读到:

https://support.google.com/accounts/answer/6010255

简而言之,谷歌不允许您通过smtplib登录,因为它已经标记了这种登录为“不太安全”,所以你要做的是去这个链接,而你登录到你的谷歌帐户,并允许访问:

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('me@gmail.com', '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”链接。从用户体验来看,更改可能需要一个小时才能生效。然后再次尝试登录过程。

不直接相关,但仍然值得指出的是,我的包试图使发送gmail消息非常快速和轻松。它还试图维护一个错误列表,并试图立即指出解决方案。

它只需要下面的代码来完成你所写的:

import yagmail
yag = yagmail.SMTP('user_me@gmail.com')
yag.send('user_you@gmail.com', 'Why,Oh why!')

或者一句话:

yagmail.SMTP('user_me@gmail.com').send('user_you@gmail.com', 'Why,Oh why!')

关于包/安装,请查看git皮普,适用于Python 2和3。

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()
    import smtplib


fromadd='from@gmail.com'
toadd='send@gmail.com'


msg='''hi,how r u'''
username='abc@gmail.com'
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

来自@David的很棒的回答,这里是Python 3没有通用的try-除了:

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()

这是

创建Gmail APP密码!< / >

创建该文件后,再创建一个名为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 = 'THEFROM@gmail.com'
gmail_app_password = 'YOUR-GOOGLE-APPLICATION-PASSWORD!!!!'


# =============================================================================
# SET THE INFO ABOUT THE SAID EMAIL
# =============================================================================
sent_from = gmail_user
sent_to = ['THE-TO@gmail.com', 'THE-TO@gmail.com']
sent_subject = "Hey Friends!"
sent_body = ("Hey, what's 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. < / >

注意:我的帐户上启用了两步认证方式。应用程序密码与此工作!(对于gmail smtp设置,您必须前往https://support.google.com/accounts/answer/185833?hl=en并遵循以下步骤)

此设置对于启用了两步验证的帐户不可用。这样的帐户需要特定于应用程序的密码来访问不太安全的应用程序。

不安全的应用程序访问…此设置不适用于启用了两步验证的帐户。”/ > < / ></p>
<h1>澄清</h1>
<p>导航到<a href=https://myaccount.google.com/apppasswords并创建如上所述的APP密码。

https://myaccount.google.com/apppasswords

下面是一个Gmail API的例子。虽然比较复杂,但这是我发现在2019年唯一有效的方法。这个例子是从以下例子中获取并修改的:

https://developers.google.com/gmail/api/guides/sending

你需要通过谷歌的网站创建一个API接口的项目。接下来,你需要为你的应用程序启用GMAIL API。创建凭证,然后下载这些凭证,保存为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's Gmail labels.
"""
creds = None
# The file token.pickle stores the user's 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("from@gmail.com", "to@gmail.com", "Subject", "Msg")
send_message( service, 'me', msg)


if __name__ == '__main__':
main()

在你的gmail帐户上启用不太安全的应用程序并使用(Python>=3.6):

import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText


gmailUser = 'XXXXX@gmail.com'
gmailPassword = 'XXXXX'
recipient = 'XXXXX@gmail.com'


message = f"""
Type your message here...
"""


msg = MIMEMultipart()
msg['From'] = f'"Your Name" <{gmailUser}>'
msg['To'] = recipient
msg['Subject'] = "Subject here..."
msg.attach(MIMEText(message))


try:
mailServer = smtplib.SMTP('smtp.gmail.com', 587)
mailServer.ehlo()
mailServer.starttls()
mailServer.ehlo()
mailServer.login(gmailUser, gmailPassword)
mailServer.sendmail(gmailUser, recipient, msg.as_string())
mailServer.close()
print ('Email sent!')
except:
print ('Something went wrong...')

意识到用Python发送电子邮件有多痛苦,所以我为它做了一个广泛的库。它也有Gmail预配置(所以你不需要记住Gmail的主机和端口):

from redmail import gmail
gmail.user_name = "you@gmail.com"
gmail.password = "<YOUR APPLICATION PASSWORD>"


# Send an email
gmail.send(
subject="An example email",
receivers=["recipient@example.com"],
text="Hi, this is text body.",
html="<h1>Hi, this is HTML body.</h1>"
)

当然你需要配置你的Gmail账号(别担心,很简单):

  1. 设置两步验证(如果尚未设置)
  2. 创建应用程序密码
  3. 将应用程序密码设置为gmail对象,完成!

红色邮件实际上是相当广泛的(包括附件,嵌入图像,发送与抄送和密件,模板与Jinja等),应该是所有你需要从电子邮件发件人。它也经过了良好的测试和文档记录。我希望它对你有用。

如何安装:

pip install redmail

文档:https://red-mail.readthedocs.io/en/latest/

源代码:https://github.com/Miksus/red-mail

注意,Gmail不允许更改发送方。发件人地址永远是你。

2022年2月更新:

尝试两件事,以便能够使用Python发送Gmail

  1. 允许不太安全的应用程序:↓↓↓

    https://myaccount.google.com/lesssecureapps

  2. 允许访问您的谷歌帐户:(点击“继续”)↓↓↓

    https://accounts.google.com/DisplayUnlockCaptcha