Python 自动发送邮件实操指南:smtplib 与 email 模块应用
在常规运维与商务场景中,每日报表推送、系统告警通知及客户跟进提醒等任务若依赖人工手动操作,极易因疲劳导致漏发或错配。利用 Python 内置的 smtplib 与 email 模块,可快速搭建稳定可靠的邮件自动化投递链路,将人工干预降至最低。
自动化部署目标与基础配置
获取 SMTP 授权凭证
现代邮箱服务商已全面弃用登录密码用于第三方客户端直连。必须前往对应邮箱的账户与安全设置页面开启 POP3/SMTP 服务,并生成独立的 SMTP 授权码。该授权码仅作为代码中的认证凭据,切勿与主账号密码混淆。
核实服务端地址与端口
不同服务商的传输协议端口存在差异,实际部署时应以官方最新文档为准:
- Gmail:
smtp.gmail.com(默认使用 TLS,端口 587) - QQ 邮箱:
smtp.qq.com(支持 SSL 端口 465 或 STARTTLS 端口 587) - 163 邮箱:
smtp.163.com(推荐 SSL 端口 465)
注意:选择端口 465 时需使用
smtplib.SMTP_SSL建立连接;选择 587 则使用smtplib.SMTP并调用starttls()升级加密通道。混用会导致握手失败。
第1步:发送纯文本通知
适用于简单的状态同步或命令行日志推送。通过 MIMEText 定义内容主体,设置标准信头后即可投递。
import smtplib
from email.mime.text import MIMEText
from email.header import Header
# 配置区(建议移至.env文件)
SMTP_SERVER = "smtp.qq.com"
SMTP_PORT = 587
SENDER_EMAIL = "your_email@qq.com"
AUTH_CODE = "你的授权码"
RECEIVER = "target@example.com"
# 1. 组装纯文本邮件对象
msg = MIMEText("【系统通知】测试环境服务已重启,当前运行正常。", "plain", "utf-8")
msg["From"] = Header("自动化监控助手", "utf-8")
msg["To"] = Header("运维负责人", "utf-8")
msg["Subject"] = Header("测试报告-日常巡检", "utf-8")
try:
# 2. 建立连接并完成认证
client = smtplib.SMTP(SMTP_SERVER, SMTP_PORT)
client.starttls()
client.login(SENDER_EMAIL, AUTH_CODE)
# 3. 执行投递并验证结果
client.sendmail(SENDER_EMAIL, [RECEIVER], msg.as_string())
print("✅ 纯文本邮件投递成功。")
except Exception as e:
print(f"❌ 投递中断:{e}")
finally:
client.quit() if 'client' in dir() else None
完成状态判定:终端输出成功提示,且目标收件箱于 1~3 分钟内收到匹配主题的行文内容。
第2步:发送带排版的 HTML 邮件
当需要展示结构化数据(如报表、图表占位)时,纯文本无法满足视觉需求。借助 MIMEMultipart 容器包裹 HTML 部分,可实现富文本投递。
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
msg = MIMEMultipart("alternative")
msg["From"] = "your_email@qq.com"
msg["To"] = "target@example.com"
msg["Subject"] = "本周业绩概览"
html_body = """
<table style="border-collapse:collapse;width:100%;">
<tr style="background:#f5f5f5;font-weight:bold;">
<td width="50%">产品名称</td><td>销售额</td>
</tr>
<tr><td>旗舰机型 A</td><td>¥ 12,450</td></tr>
<tr><td>便携款 B</td><td>¥ 8,320</td></tr>
</table>
""
msg.attach(MIMEText(html_body, "html", "utf-8"))
# 复用前文的 client 登录逻辑执行发送
client.sendmail(msg["From"], msg["To"].split(","), msg.as_string())
print("✅ 含排版内容的邮件已发出。")
client.quit()
完成状态判定:邮件客户端解析出表格样式而非原始 HTML 源码,字体与间距符合预期。
第3步:关联本地文件并发送附件
业务流转常伴随 CSV、PDF 或 Excel 导出物的传递。使用 MIMEApplication 可将二进制流封装为邮件附件节点。
from email.mime.application import MIMEApplication
def send_attachment_report(file_path):
msg = MIMEMultipart()
msg["From"] = SENDER_EMAIL
msg["To"] = RECEIVER
msg["Subject"] = "附件:月度财务结算表"
msg.attach(MIMEText("请查收附件中的最新数据归档。", "plain", "utf-8"))
with open(file_path, "rb") as f:
part = MIMEApplication(f.read(), Name="Financial_Report.xlsx")
part["Content-Disposition"] = f'attachment; filename="Financial_Report.xlsx"'
msg.attach(part)
client.sendmail(SENDER_EMAIL, [RECEIVER], msg.as_string())
print(f"✅ 附件 {file_path} 已随信寄出。")
client.quit()
# 调用示例:send_attachment_report(r"E:\data\report.xlsx")
风险提示:发送前务必校验文件路径是否存在,且单封邮件总体积建议控制在运营商限制内(通常不超过 20MB),超大文件应改用云存储链接分享。
工程化加固与异常恢复
敏感信息隔离管理
硬编码凭证会引发严重的泄露风险。生产环境请使用 python-dotenv 加载外部配置文件:
import os
from dotenv import load_dotenv
load_dotenv()
SERVER = os.getenv("SMTP_HOST")
PWD = os.getenv("SMTP_AUTH_CODE")
建议将 .env 文件加入版本控制忽略列表(如 .gitignore),并通过 CI/CD 平台的安全变量注入机制同步至运行环境。
网络抖动下的重试策略
SMTP 握手期间可能遭遇临时拒绝(如 4xx 错误)。引入固定间隔的重试逻辑可提高交付率:
import time
def retry_send(max_attempts=3, interval=5):
for attempt in range(max_attempts):
try:
client.sendmail(SENDER_EMAIL, [RECEIVER], msg.as_string())
return True
except Exception as err:
print(f"⚠️ 第 {attempt+1} 次尝试失败:{err}")
if attempt < max_attempts - 1:
time.sleep(interval)
else:
raise RuntimeError("所有重试耗尽,任务终止。")
高并发场景的连接复用
避免为每封邮件频繁创建/销毁 TCP 连接。初始化一次 smtplib 实例后,循环调用 sendmail 即可。完成后统一执行 quit() 释放资源。
常见问题排查
- SMTPAuthenticationError 报错:通常源于误填登录密码或授权码未开启/已过期。请重新生成凭证并检查输入无误。
- 落入垃圾邮件夹:检查是否使用了通用免费域名发送营销话术。规范设置 SPF/DKIM 记录,控制单次群发频率,并在信头补充退订指引。
- 中文显示乱码:所有构造函数的第三个参数必须显式声明
utf-8;文件名中的特殊字符建议使用 base64 编码后再填入 filename 字段。
总结
通过合理编排 smtplib 传输层与 email 表现层,开发者可零成本构建企业级邮件分发管道。掌握凭证安全管理、HTML 模板渲染与断线重试机制后,可将日报推送、告警拦截等高频动作彻底交由后台定时任务调度,显著提升团队运转效率。
以上就是 Python 自动发送邮件配置的详细内容,更多关于 Python 办公自动化脚本的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













