Python3 SMTP发送邮件实战:从基础构造到QQ邮箱SSL配置

何川
何川
发布时间:2026-10-10| 5人浏览过
原创

本文详细讲解如何利用 Python3 内置的 smtplib 与 email 模块,通过 SMTP 协议完成各类邮件自动发送。涵盖纯文本、HTML 富文本、附件打包及内嵌图片构造方法,并演示如何配置 QQ 邮箱授权码进行安全 SSL 连接,附带高频报错排查指南。

SMTP 协议与核心库基础

实现邮件自动投递需理解底层通信规则与 Python 标准库分工。SMTP(Simple Mail Transfer Protocol)负责定义邮件源端与接收端之间的传输规范。Python 无需安装第三方依赖即可调用两个核心模块:

  • smtplib:封装 SMTP 客户端逻辑,负责建立网络连接、身份认证与数据投递。
  • email:负责按 RFC 规范组装邮件报文头(From/To/Subject)与正文载荷(文本/HTML/附件/多部分组合),确保邮件结构符合服务端校验标准。

标准连接与发送流程

所有邮件发送均遵循相同生命周期:实例化对象 → 建立 TCP 连接 → 登录认证 → 组装报文 → 执行投递 → 关闭会话。

第1步:初始化 SMTP 客户端对象

创建连接对象时需明确服务器地址与端口策略。非加密默认端口为 25,现代邮箱普遍强制要求 TLS/SSL 加密,推荐直接使用 SSL 专用类与端口 465。

import smtplib
# 语法结构:smtplib.SMTP(host, port, local_hostname)
# 常规明文连接示例(仅适用内部自建服务)
smtp_obj = smtplib.SMTP('localhost', 25)

第2步:调用 sendmail 执行投递

连接成功后,使用 sendmail() 提交报文。该方法严格校验收发件人列表格式,即便单收件人也必须包裹于列表中。

smtp_obj.sendmail(
    from_addr='user@example.com',
    to_addrs=['target@example.com'],
    msg=raw_message_string
)

实战:构建不同类型邮件

第3步:发送纯文本通知邮件

适用于系统告警或简短状态同步。核心是使用 MIMEText 声明主体类型为 'plain',并通过头部字段设置发件人昵称与主题。

import smtplib
from email.mime.text import MIMEText
from email.header import Header

sender = 'sender@example.com'
receivers = ['receiver@example.com']

msg = MIMEText('Python 邮件发送测试:这是一段纯文本内容', 'plain', 'utf-8')
msg['From'] = Header('发件人昵称', 'utf-8')
msg['To'] = Header('收件人昵称', 'utf-8')
msg['Subject'] = Header('Python SMTP 纯文本测试', 'utf-8')

try:
    smtp_obj = smtplib.SMTP('localhost')
    smtp_obj.sendmail(sender, receivers, msg.as_string())
    print("纯文本邮件投递成功")
except smtplib.SMTPException as e:
    print(f"投递失败: {e}")

第4步:发送含排版与表格的 HTML 邮件

适合推送数据报表或活动公告。只需将 MIMEText 的 _subtype 参数改为 'html',正文可包含标准 CSS 样式与 DOM 元素。

import smtplib
from email.mime.text import MIMEText
from email.header import Header

sender = 'sender@example.com'
receivers = ['receiver@example.com']

html_content = """
<p>Python 邮件发送测试...</p>
<p>这是 <b>HTML 格式</b> 的邮件,支持富文本:</p>
<p>1. 点击访问 <a href="http://www.example.com">示例链接</a></p>
<table border="1">
  <tr><th>姓名</th><th>年龄</th></tr>
  <tr><td>张三</td><td>25</td></tr>
  <tr><td>李四</td><td>30</td></tr>
</table>
"""

msg = MIMEText(html_content, 'html', 'utf-8')
msg['From'] = Header('发件人昵称', 'utf-8')
msg['To'] = Header('收件人昵称', 'utf-8')
msg['Subject'] = Header('Python SMTP HTML 邮件测试', 'utf-8')

try:
    smtp_obj = smtplib.SMTP('localhost')
    smtp_obj.sendmail(sender, receivers, msg.as_string())
    print("HTML 邮件投递成功")
except smtplib.SMTPException as e:
    print(f"投递失败: {e}")

第5步:附加文件实现带附件发送

当需要分发日志、表格或压缩包时,需使用 MIMEMultipart 构建混合容器。附件读取时必须以二进制模式 'rb' 打开,并正确声明 Content-Disposition 为 attachment。

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

sender = 'sender@example.com'
receivers = ['receiver@example.com']

msg = MIMEMultipart()
msg['From'] = Header('发件人昵称', 'utf-8')
msg['To'] = Header('收件人昵称', 'utf-8')
msg['Subject'] = Header('Python SMTP 带附件测试', 'utf-8')
msg.attach(MIMEText('这是带附件的邮件正文...', 'plain', 'utf-8'))

# 添加第一个附件
with open('test.txt', 'rb') as f:
    att1 = MIMEText(f.read(), 'base64', 'utf-8')
    att1['Content-Type'] = 'application/octet-stream'
    att1['Content-Disposition'] = 'attachment; filename="report.txt"'
    msg.attach(att1)

try:
    smtp_obj = smtplib.SMTP('localhost')
    smtp_obj.sendmail(sender, receivers, msg.as_string())
    print("带附件邮件投递成功")
except smtplib.SMTPException as e:
    print(f"投递失败: {e}")

第6步:通过 Content-ID 在正文中嵌入图片

若希望图片直接渲染在邮件视图中而非作为独立附件下载,需采用 MIMEMultipart('related') 配合 cid: 引用机制。HTML 中的 src 属性值必须与图片主体的 Content-ID 头严格一致。

import smtplib
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.header import Header

sender = 'sender@example.com'
receivers = ['receiver@example.com']

msgRoot = MIMEMultipart('related')
msgRoot['From'] = Header('发件人昵称', 'utf-8')
msgRoot['To'] = Header('收件人昵称', 'utf-8')
msgRoot['Subject'] = Header('Python SMTP 内嵌图片测试', 'utf-8')

# 备选方案容器:兼容不支持 HTML 的客户端
msgAlternative = MIMEMultipart('alternative')
msgRoot.attach(msgAlternative)

html_body = """<p>图片已嵌入正文:</p><p><img src="cid:logo_img"></p>"""
msgAlternative.attach(MIMEText(html_body, 'html', 'utf-8'))

with open('logo.png', 'rb') as img_f:
    img_msg = MIMEImage(img_f.read())
    img_msg.add_header('Content-ID', '<logo_img>')
    msgRoot.attach(img_msg)

try:
    smtp_obj = smtplib.SMTP('localhost')
    smtp_obj.sendmail(sender, receivers, msgRoot.as_string())
    print("内嵌图片邮件投递成功")
except smtplib.SMTPException as e:
    print(f"投递失败: {e}")

对接第三方 SMTP 服务(QQ 邮箱配置)

生产环境通常放弃本地 sendmail 代理,转而调用运营商提供的标准化 SMTP 网关。该方式跨平台兼容,但必须开启服务权限并使用授权码替代原始密码。

第7步:启用 SSL 通道完成安全登录与投递

准备工作:登录目标邮箱进入设置 → 账户,找到 POP3/SMTP/IMAP 服务区域,开启 IMAP/SMTP 开关并完成短信验证,获取 16 位授权码。

参数配置:QQ 邮箱 SMTP 主机为 smtp.qq.com,SSL 专属端口为 465。连接时必须使用 smtplib.SMTP_SSL 类。

import smtplib
from email.mime.text import MIMEText
from email.utils import formataddr

my_sender = '123456@qq.com'      # 发件人账号
my_pass = 'abcdefghijklmnop'     # 授权码(非登录密码)
my_user = '654321@qq.com'        # 收件人账号

def send_ssl_mail():
    ret = True
    try:
        msg = MIMEText('这是使用 QQ 邮箱 SMTP 发送的测试邮件', 'plain', 'utf-8')
        msg['From'] = formataddr(["发件人", my_sender])
        msg['To'] = formataddr(["收件人", my_user])
        msg['Subject'] = "Python SMTP QQ 邮箱安全测试"

        server = smtplib.SMTP_SSL("smtp.qq.com", 465)
        server.login(my_sender, my_pass)
        server.sendmail(my_sender, [my_user], msg.as_string())
        server.quit()
    except Exception as e:
        print(f"发送失败原因:{e}")
        ret = False
    return ret

if send_ssl_mail():
    print("QQ 邮箱安全投递成功")
else:
    print("QQ 邮箱安全投递失败")

其他服务商(如网易 163、企业微信等)接入逻辑一致:替换 host、port 并获取对应授权凭证即可复用上述代码结构。

高频异常排查

报错现象排查方向解决动作
SMTPAuthenticationError凭证不匹配或服务未激活重新生成授权码;登录网页端确认 IMAP/SMTP 开关处于开启状态
SMTPConnectError网络拦截或参数错误核对 smtp.qq.com 等标准域名;检查本地防火墙/代理是否阻断 465 端口
正文乱码或图片缺失编码声明缺失或 CID 错位MIMEText 强制指定 'utf-8';检查 HTML src="cid:xxx" 与 add_header('Content-ID', '<xxx>') 标识完全闭环
投递成功但收不到信反垃圾策略拦截移入垃圾箱白名单;避免群发高频敏感词;首次发送可先抄送自身域名验证链路

总结

掌握 smtplib 的连接控制与 email 模块的结构化拼装,即可灵活应对日常运维监控、定时报表推送、用户验证信等自动化场景。配合 schedule 调度器与 CSV 循环读取,可进一步升级为批量个性化触达系统。以上就是Python3 SMTP发送邮件实战操作的详细内容,更多关于Python电子邮件自动化与smtplib库调用的资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。