我试图使用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()
在您的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...')
我遇到过类似的问题,并无意中发现了这个问题。我得到一个SMTP身份验证错误,但我的用户名/ pass是正确的。下面是解决问题的方法。我读到:
https://support.google.com/accounts/answer/6010255
简而言之,谷歌不允许您通过smtplib登录,因为它已经标记了这种登录为“不太安全”,所以你要做的是去这个链接,而你登录到你的谷歌帐户,并允许访问:
https://www.google.com/settings/security/lesssecureapps
一旦设置好了(见下面的截图),它就可以工作了。
登录现在工作:
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”链接。从用户体验来看,更改可能需要一个小时才能生效。然后再次尝试登录过程。
你需要在直接运行到STARTTLS之前说EHLO:
server = smtplib.SMTP('smtp.gmail.com:587')
server.ehlo()
server.starttls()
此外,您应该真正创建From:、To:和Subject:消息头,用空行与消息体分隔,并使用CRLF作为EOL标记。
E.g.
msg = "\r\n".join([
"From: user_me@gmail.com",
"To: user_you@gmail.com",
"Subject: Just a message",
"",
"Why, oh why"
])
注意:
为了做到这一点,你需要在gmail帐户配置中启用“允许不太安全的应用程序”选项。否则,当gmail检测到一个非谷歌应用程序试图登录你的帐户时,你会得到一个“关键安全警报”。
下面是一个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...')