Python3 SMTP发送邮件:从零开始掌握自动化邮件功能
在日常开发中,我们常常需要通过程序自动发送通知、报告或验证码。比如:用户注册成功后发送欢迎邮件、系统异常时发送告警、定时任务生成报表并发送给负责人……这些场景背后,都离不开一个基础却强大的功能——邮件发送。
而 Python3 提供了内置的 smtplib 模块,可以轻松实现通过 SMTP 协议发送邮件。今天,我们就来手把手带你掌握 Python3 SMTP发送邮件 的完整流程,无论你是初学者还是有一定经验的开发者,都能快速上手。
什么是 SMTP?它和邮件系统的关系是什么?
想象一下,你写了一封信,想寄给远方的朋友。你不能直接把信塞进邮局的信箱里,而是要先交给邮局工作人员,由他们按照地址分拣、运输、最终投递到收件人手中。
在互联网世界中,SMTP(Simple Mail Transfer Protocol,简单邮件传输协议)就是这个“邮局工作人员”。它负责将你的邮件从发件人服务器“运输”到收件人服务器。
当你使用 Python3 发送邮件时,程序会通过 SMTP 协议连接到邮件服务商的服务器(如 QQ 邮箱、163 邮箱、Gmail 等),把邮件内容“交给”它,再由它完成后续的投递工作。
✅ 小贴士:SMTP 不是收邮件的协议,它只负责“发”邮件。收邮件通常用 POP3 或 IMAP 协议。
准备工作:获取邮箱授权码和配置信息
在开始编码之前,你必须准备好以下信息:
- 邮箱账号(如:example@163.com)
- 邮箱密码(或授权码)
- SMTP 服务器地址
- 端口号(通常为 25、465 或 587)
- 是否启用 SSL/TLS 加密
📌 注意:现在很多邮箱服务商(如 QQ、163、Gmail)不再允许使用明文密码登录,必须开启“客户端授权码”功能。
以 QQ 邮箱为例:
- 登录 QQ 邮箱网页版
- 进入「设置」→「账户」→ 找到「POP3/SMTP 服务」
- 开启「SMTP 服务」,系统会生成一个 16 位的授权码
- 记下以下信息:
- 发件人邮箱:example@qq.com
- 授权码:xxxxxxxxxxxxxx(不要泄露!)
- SMTP 服务器:smtp.qq.com
- 端口:587(使用 TLS 加密)或 465(使用 SSL 加密)
| 项目 | 示例值 |
|---|---|
| 发件人邮箱 | example@qq.com |
| 授权码 | a1b2c3d4e5f6g7h8 |
| SMTP 服务器 | smtp.qq.com |
| 端口 | 587(TLS)或 465(SSL) |
| 加密方式 | TLS(推荐 587)或 SSL(465) |
基础代码实现:发送一封简单的文本邮件
下面是一个最基础的 Python3 SMTP发送邮件 示例,我们发送一封纯文本邮件给指定收件人。
import smtplib
from email.mime.text import MIMEText
from email.header import Header
sender_email = "example@qq.com" # 发件人邮箱
sender_password = "a1b2c3d4e5f6g7h8" # 授权码,不是登录密码
smtp_server = "smtp.qq.com" # SMTP 服务器地址
smtp_port = 587 # 端口号(587 为 TLS,465 为 SSL)
receiver_email = "recipient@example.com" # 收件人邮箱
message = MIMEText("这是一封由 Python3 发送的测试邮件。", "plain", "utf-8")
message["From"] = Header("Python 邮件发送器", "utf-8")
message["To"] = Header("收件人", "utf-8")
message["Subject"] = Header("测试邮件 - Python3 SMTP发送邮件", "utf-8")
try:
# 创建 SMTP 客户端(使用 TLS 加密)
server = smtplib.SMTP(smtp_server, smtp_port)
server.starttls() # 启用 TLS 加密(推荐 587 端口使用)
# 登录邮箱
server.login(sender_email, sender_password)
# 发送邮件
server.sendmail(sender_email, receiver_email, message.as_string())
print("✅ 邮件发送成功!")
except Exception as e:
print(f"❌ 邮件发送失败:{e}")
finally:
# 关闭连接
server.quit()
代码逐行解析:
MIMEText:创建一个文本类型邮件对象,"plain"表示纯文本,"utf-8"指定编码。Header:用于设置邮件头(如 From、To、Subject),支持中文。smtplib.SMTP:连接 SMTP 服务器,指定服务器地址和端口。starttls():启用 TLS 加密,防止邮件内容被窃听。login():使用邮箱账号和授权码登录。sendmail():发送邮件,参数为发件人、收件人、邮件内容(需转为字符串)。quit():关闭 SMTP 连接,释放资源。
⚠️ 安全提示:切勿将授权码硬编码在代码中!生产环境建议使用环境变量或配置文件。
高级功能:发送 HTML 邮件与附件
发送 HTML 邮件
有时候你希望邮件更美观,比如包含加粗、链接、图片等。这时可以使用 HTML 格式。
html_content = """
<html>
<body>
<h2>您好!</h2>
<p>这是一封 <strong>HTML 格式</strong> 的邮件。</p>
<p>您可以通过 <a href="https://www.example.com">点击这里</a> 查看更多信息。</p>
</body>
</html>
"""
message = MIMEText(html_content, "html", "utf-8")
message["From"] = Header("Python 邮件发送器", "utf-8")
message["To"] = Header("收件人", "utf-8")
message["Subject"] = Header("HTML 邮件测试", "utf-8")
添加附件
如果你要发送一个文件(如 Excel 报表、PDF 文档),可以这样添加附件:
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email import encoders
msg = MIMEMultipart()
msg["From"] = Header("Python 发送器", "utf-8")
msg["To"] = Header("收件人", "utf-8")
msg["Subject"] = Header("带附件的邮件", "utf-8")
msg.attach(MIMEText("<p>请查收附件中的报表。</p>", "html", "utf-8"))
filename = "report.xlsx"
with open(filename, "rb") as f:
part = MIMEBase("application", "octet-stream")
part.set_payload(f.read())
encoders.encode_base64(part)
part.add_header(
"Content-Disposition",
f"attachment; filename={filename}"
)
msg.attach(part)
server = smtplib.SMTP(smtp_server, smtp_port)
server.starttls()
server.login(sender_email, sender_password)
server.sendmail(sender_email, receiver_email, msg.as_string())
server.quit()
💡 小知识:
MIMEBase是通用的二进制数据封装,octet-stream表示任意二进制数据。
常见问题与解决方案
| 问题 | 原因 | 解决方案 |
|---|---|---|
SMTPAuthenticationError: 535 |
授权码错误或未开启 SMTP 服务 | 检查授权码是否正确,确认在邮箱设置中已开启 SMTP |
ssl.SSLError |
端口或加密方式不匹配 | 使用 587 端口 + starttls();或 465 端口 + smtplib.SMTP_SSL() |
| 邮件被标记为垃圾邮件 | 内容或发送频率异常 | 避免使用大量感叹号、链接,控制发送频率 |
| 无法连接服务器 | 网络或防火墙限制 | 检查网络,或尝试使用代理 |
实用建议:如何让邮件发送更稳定?
-
使用环境变量管理敏感信息
用os.getenv("EMAIL_PASSWORD")读取授权码,避免硬编码。 -
添加重试机制
网络波动可能导致发送失败,可尝试 2~3 次重试。 -
记录日志
使用logging模块记录发送状态,便于排查问题。 -
使用上下文管理器
确保server.quit()一定执行,避免连接泄露。 -
测试阶段使用测试邮箱
先发送给自己的测试邮箱,确认无误再发给正式收件人。
总结:Python3 SMTP发送邮件的核心要点
通过本文的学习,你应该已经掌握了 Python3 SMTP发送邮件 的核心流程:
- 理解 SMTP 的作用:它是邮件的“快递员”
- 准备好邮箱授权码和服务器配置
- 使用
smtplib和email模块构建邮件对象 - 支持发送纯文本、HTML、带附件的邮件
- 处理常见错误,提升发送稳定性
无论你是做自动化运维、开发 Web 应用,还是搭建监控告警系统,Python3 SMTP发送邮件 都是一项非常实用的技能。它让你的程序具备“主动沟通”的能力,真正实现智能化运维。
下一次,当你的程序需要“告诉用户一件事”时,别忘了:用 Python 写一封邮件,比任何语言都来得简洁高效。
📣 最后提醒:请勿滥用邮件发送功能,避免被标记为垃圾邮件。合理使用,才是技术的真正价值。