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

Mah*_*ori 272 python email gmail smtp

我正在尝试使用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.
Run Code Online (Sandbox Code Playgroud)

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()
Run Code Online (Sandbox Code Playgroud)

Dav*_*wii 286

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"
Run Code Online (Sandbox Code Playgroud)

如果要使用端口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'
Run Code Online (Sandbox Code Playgroud)

  • 不幸的是不再工作:smtplib.SMTPAuthenticationError:(534,'5.7.14 <https://accounts.google.com/ContinueSignIn?sarp=1&scc=1&plt=AKgnsbuRb ...请通过您的网络浏览器登录并\n5.7.14然后再试一次.\n5.7.14了解更多信息,请访问\n5.7.14 https://support.google.com/mail/bin/answer.py?answer=78754 ...然后我收到了来自谷歌的邮件,已经发生了可疑的连接尝试. (18认同)
  • @royskatt:我刚刚解决了你面临的问题.谷歌有一个设置允许访问不太安全的应用程序,你只需将其打开.你可以从那里:谷歌 - >我的帐户 - >登录和安全 - >连接的应用程序和网站 - >向下滚动,你会发现'允许不太安全的应用程序' (14认同)
  • @royskatt - 您需要做的就是创建一个应用密码并使用它来代替您的帐户密码.在此处创建应用密码:https://security.google.com/settings/security/apppasswords (11认同)
  • 非常好的样品谢谢.有人认为我注意到如果我想使用SSL连接我必须删除server.starttls() (2认同)
  • 如果您的 gmail 受双因素身份验证保护,您必须首先[生成应用程序特定密码](https://security.google.com/settings/security/apppasswords?pli=1) --&gt; 然后使用该应用程序-上面示例代码中的密码(这非常重要,因为这样您就不会在任何地方以明文形式写下您的密码,并且您可以随时撤销应用程序密码)。 (2认同)

Mat*_*ttH 203

EHLO在直接进入之前你需要说STARTTLS:

server = smtplib.SMTP('smtp.gmail.com:587')
server.ehlo()
server.starttls()
Run Code Online (Sandbox Code Playgroud)

此外,你应该真正创造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"
  ])
Run Code Online (Sandbox Code Playgroud)

  • 截至2014年8月,现在提出了smtplib.SMTPAuthenticationError:(534,'5.7.9需要特定于应用程序的密码. (14认同)
  • 但对我来说,我必须启用"应用"密码才能使用@google帐户登录以通过python发送电子邮件:https://support.google.com/accounts/answer/185833?hl = en&ctx = ch_DisplayUnlockCaptcha (6认同)
  • 调用 server.sendmail(fromaddr, toaddrs, msg) 第二个参数,toaddrs 必须是一个列表,toaddrs = ['user_me@gmail.com'] (2认同)

rad*_*tek 128

我遇到了类似的问题,偶然发现了这个问题.我收到了SMTP身份验证错误,但我的用户名/密码是正确的.这是修复它的原因.我看了这个:

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

简而言之,Google不允许您通过smtplib登录,因为它已将此类登录标记为"不太安全",因此您需要做的是在登录Google帐户时转到此链接,并允许访问:

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')
Run Code Online (Sandbox Code Playgroud)

更改后的回复:

(235, '2.7.0 Accepted')
Run Code Online (Sandbox Code Playgroud)

事先回复:

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')
Run Code Online (Sandbox Code Playgroud)

还是行不通?如果你仍然得到SMTPAuthenticationError,但现在代码是534,因为它的位置是未知的.点击此链接:

https://accounts.google.com/DisplayUnlockCaptcha

单击"继续",这将为您提供10分钟的注册新应用程序.所以现在继续进行另一次登录尝试,它应该工作.

更新:这似乎没有立即工作你可能会在smptlib中遇到这个错误一段时间:

235 == 'Authentication successful'
503 == 'Error: already authenticated'
Run Code Online (Sandbox Code Playgroud)

消息说使用浏览器登录:

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')
Run Code Online (Sandbox Code Playgroud)

启用'lesssecureapps'后,去喝咖啡,回来,再次尝试'DisplayUnlockCaptcha'链接.根据用户体验,更改可能需要一个小时才能启动.然后再次尝试登录过程.

  • 另外,请留下半小时到一小时的时间来更改设置.我创建了一个新帐户,禁用了所有增加的安全性,但仍然遇到了同样的错误.大约一个小时后,一切都奏效了. (5认同)
  • 是的,谢谢 !在使用烧瓶邮件时发生了 (3认同)
  • 如果您启用了“两步验证”,则无法启用安全性较低的应用。最好和最安全的选择是按照建议的那样启用“ apppassword” https://security.google.com/settings/security/apppasswords,它的工作原理就像一个超级按钮 (2认同)
  • 当我点击 apppasswords 链接时,我所有的 Google 帐户都会收到“您正在寻找的设置不适用于您的帐户”错误。 (2认同)

Ric*_*son 17

你有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')
Run Code Online (Sandbox Code Playgroud)

  • 如果你的类只有两个方法,其中一个是\ _ _ _ _ init__,只需使用一个函数. (27认同)
  • 谁用OOP打倒了?:-) (4认同)
  • 如果您想初始化客户端并将其传递到代码的其他部分,而不是传递电子邮件和密码,那么使用类会很好。或者,如果您想发送多条消息而无需每次都传递电子邮件和密码。 (2认同)

Luk*_*pin 17

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

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

您需要通过他们的网站使用 Google 的 API 接口创建一个项目。接下来,您需要为您的应用启用 GMAIL API。创建凭据,然后下载这些凭据,将其保存为凭据.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()
Run Code Online (Sandbox Code Playgroud)


Fro*_*oyo 14

你可以在这里找到它: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())
Run Code Online (Sandbox Code Playgroud)

  • 加1,因为构建MIME比对您自己的格式字符串进行硬编码更好。简单文本消息是否需要MIMEMultipart?还是以下内容也正确:http://stackoverflow.com/a/6270987/895245 (2认同)

Pas*_*ten 11

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

它实际上只需要这个代码就可以完全按照你所写的那样做:

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

或者一个班轮:

yagmail.SMTP('user_me@gmail.com').send('user_you@gmail.com', 'Why,Oh why!')
Run Code Online (Sandbox Code Playgroud)

对于软件包/安装,请查看适用于Python 2和3的gitpip.


小智 11

2022 年 12 月更新:

\n

您需要使用应用程序密码来允许您的应用程序访问您的谷歌帐户。

\n

使用应用程序密码登录

\n
\n

应用密码是一个 16 位密码,可向安全性较低的应用或设备\n提供访问您的 Google 帐户的权限。应用程序密码\只能与启用了两步验证的帐户一起使用。

\n
\n

此外,自 2022 年 5 月 30 日起,Google 不允许您的应用通过用户名(电子邮件地址)密码访问您的 Google 帐户。因此,现在您需要用户名(电子邮件地址)应用密码来访问您的 Google 帐户。

\n

安全性较低的应用程序和您的 Google 帐户

\n
\n

为了确保您帐户的安全,从 2022 年 5 月 30 日起,\xe2\x80\x8b\xe2\x80\x8bGoogle 将不再支持使用要求您\n登录 Google 帐户的第三方应用或设备只有您的用户名和\n密码。

\n
\n

如何生成应用程序密码:

\n

首先,点击9 个点中的“帐户”

\n

在此输入图像描述

\n

然后,单击“安全”中的“应用程序密码”。*在生成应用程序密码之前不要忘记打开两步验证,否则您无法生成应用程序密码

\n

在此输入图像描述

\n

然后,单击其他(自定义名称)

\n

在此输入图像描述

\n

然后,输入您的应用程序名称,然后单击“生成”

\n

在此输入图像描述

\n

最后,您可以生成应用程序密码xylnudjdiwpojwzm

\n

在此输入图像描述

\n

因此,您的代码与上面的应用程序密码如下所示:

\n
import smtplib\n\nfromaddr = \'user_me@gmail.com\'\ntoaddrs  = \'user_you@gmail.com\'\nmsg = \'Why,Oh why!\'\nusername = \'user_me@gmail.com\'\npassword = \'xylnudjdiwpojwzm\' # Here\nserver = smtplib.SMTP(\'smtp.gmail.com:587\')\nserver.starttls()\nserver.login(username,password)\nserver.sendmail(fromaddr, toaddrs, msg)\nserver.quit()\n\n
Run Code Online (Sandbox Code Playgroud)\n

另外,在Djangosettings.py中使用上面的应用程序密码中如下所示:

\n
# "settings.py"\n\nEMAIL_BACKEND = \'django.core.mail.backends.smtp.EmailBackend\'\nEMAIL_HOST = \'smtp.gmail.com\'\nEMAIL_PORT = 587\nEMAIL_USE_TLS = True\nEMAIL_HOST_USER = \'myaccount@gmail.com\'\nEMAIL_HOST_PASSWORD = \'xylnudjdiwpojwzm\' # Here\n
Run Code Online (Sandbox Code Playgroud)\n


Jay*_*zzo 9

这个作品

创建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 = "Where are all my Robot Women at?"
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)
Run Code Online (Sandbox Code Playgroud)

所以,如果你成功了,会看到这样的图像:

我通过向自己发送电子邮件进行测试.

发送成功邮件.

注意:我的帐户启用了两步验证.App密码适用于此!

此设置不适用于启用了两步验证的帐户.此类帐户需要特定于应用程序的密码才能访问安全性较低的应用

不太安全的应用访问权限...此设置不适用于启用了两步验证的帐户.

  • 所有其他都是较旧的帖子,可能无法正常工作,但这是 100% 有效的。请生成应用程序密码。感谢你的回答 (3认同)
  • 我有点惊讶的是这个解决方案没有得到更多的支持。我没有尝试过所有其他的,但我已经尝试过几个,只有这个是开箱即用的,零修修补补。 (2认同)

mik*_*sus 6

意识到通过 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>"
)
Run Code Online (Sandbox Code Playgroud)

当然,您需要配置您的 Gmail 帐户(不用担心,这很简单):

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

Red Mail 实际上相当广泛(包括附件、嵌入图像、通过抄送和密件抄送发送、使用 Jinja 模板等),希望能够满足您对电子邮件发件人的所有需求。它也经过了充分的测试和记录。希望对你有帮助。

安装:

pip install redmail
Run Code Online (Sandbox Code Playgroud)

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

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

请注意,Gmail 不允许更改发件人。发件人地址始终是您。

  • 简化这个工作做得很好。奇迹般有效。荣誉。 (2认同)