You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

谷歌不再支持单纯账号密码登录后如何用Python发送邮件

谷歌新政策下Python发送邮件的可行方案

Gmail可用方案

谷歌停止支持用户名+普通密码的第三方登录后,Gmail依然可以通过两种方式用Python发信:

  • 应用专用密码方式:先给谷歌账号开启两步验证,之后在账号安全设置页生成16位长度的应用专用密码,代码中原先填写账号普通密码的位置替换为这个专用密码即可,原有smtp.gmail.com、587端口的SMTP配置无需修改。注意:未开启两步验证的账号无法生成应用专用密码
  • Gmail API + OAuth2授权方式:通过谷歌官方开放接口完成OAuth2.0授权后发信,无需存储账号固定密码,安全性更高,但配置流程相对复杂,适合生产环境使用,需要在对应云服务控制台创建项目、启用Gmail服务、配置授权凭据。

其他邮箱服务商支持

完全可以切换为其他邮箱服务商的账号发信,不受谷歌政策影响,只要替换对应SMTP配置、按服务商要求完成SMTP服务开通即可,常见可选服务商:

  • 个人邮箱类:QQ邮箱、163邮箱、Outlook/Hotmail、Zoho Mail等,这类个人邮箱一般需要先在网页端邮箱设置中开启SMTP服务,生成专属授权码作为登录密码使用
  • 专业邮件发送服务类:SendGrid、Mailgun、各类企业邮箱等,这类服务发信送达率更高,适合批量发信、正式业务通知场景
现有代码存在的其他问题

除了SMTP相关配置外,你贴的代码还有4个明确问题:

  • 变量名写错了:s.sendmail()第一个参数你写的是from_email_addr,但函数传进来的发件人参数叫fromaddr,跑的时候直接报NameError,把这里换成fromaddr就行
  • 文件资源未释放:你用open()打开附件之后没有调用close(),程序跑多了会占着文件句柄不释放,要么操作完手动关文件,要么直接用with open()上下文管理器,操作完自动关闭,省得出错
  • 缩进语法错误:你贴的代码里函数体所有代码都顶格写了,Python靠缩进区分代码块,直接跑会报语法错误,函数内部的逻辑统一缩进4个空格
  • 连接逻辑要适配端口:如果你换用465这类SSL直连加密端口,别用普通的smtplib.SMTP,换成smtplib.SMTP_SSL,也不用再调用starttls();创建SMTP连接时最好加个timeout参数,不然网络异常时程序会一直卡死无响应。

修正后可运行参考代码(以Gmail应用专用密码方式为例)

import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email import encoders

def send_email_fct(filename, filepath, fromaddr, mdpfrom, toaddr):
    """ filename: 待发送附件的文件名(含后缀)
         filepath: 待发送附件的本地路径
         fromaddr: 发件人邮箱地址
         mdpfrom: 发件人邮箱对应的应用专用密码/授权码
         toaddr: 收件人邮箱地址"""
    msg = MIMEMultipart()
    msg['From'] = fromaddr
    msg['To'] = toaddr
    msg['Subject'] = "data file"

    body_email = "Body_of_the_mail"
    msg.attach(MIMEText(body_email, 'plain'))

    # 用with上下文管理器自动关闭文件,避免资源泄漏
    with open(filepath, 'rb') as attachment:
        p = MIMEBase('application', 'octet-stream')
        p.set_payload(attachment.read())
    encoders.encode_base64(p)
    p.add_header('Content-Disposition', f"attachment; filename= {filename}")
    msg.attach(p)

    # 增加超时参数,避免网络异常时程序无限等待
    s = smtplib.SMTP('smtp.gmail.com', 587, timeout=10)
    s.starttls()
    s.login(fromaddr, mdpfrom)
    text = msg.as_string()
    # 修正原代码变量名不匹配问题
    s.sendmail(fromaddr, toaddr, text)
    s.quit()

内容的提问来源于stack exchange,提问作者X0-user-0X

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 04:51:37