我试图使用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()

当前回答

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

其他回答

来自@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()

意识到用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账号(别担心,很简单):

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

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

如何安装:

pip install redmail

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

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

注意,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...')

现在有一个gmail API,它可以让你通过REST发送电子邮件,阅读电子邮件和创建草稿。 与SMTP调用不同,它是非阻塞的,这对于在请求线程中发送电子邮件的基于线程的web服务器(如python web服务器)来说是一件好事。这个API也非常强大。

当然,电子邮件应该交给一个非web服务器队列,但有选择是很好的。

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

下面是一个要点:

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