报告自己定时发,用 Python的smtplib 发一封带附件的邮件的简单方法

举报
yd_233495430 发表于 2026/09/05 08:42:03 2026/09/05
【摘要】 用 Python 标准库 smtplib + email 发邮件:MIMEText 发纯文本(或 html 排版),MIMEMultipart + MIMEApplication 加附件,端口 465(SSL)/587(starttls) 与授权码、密码走环境变量等说明,附频率限制与批量发信用事务邮件服务的建议。

每天把一份数据报表、一份日志摘要发到邮箱,手动发迟早会忘,月底对账才发现少了好几天的。Python 标准库自带 smtplib 和 email 模块,不装任何第三方包,几行就能把文本甚至附件发出去;再挂上系统的定时任务(Linux 的 crontab、Windows 的任务计划),就彻底自动化,到点自己发。本文把"发纯文本"和"发带附件"两种都跑通。

一、发一封纯文本邮件

一封邮件本质是一段带头的文本:Subject/From/To 是头,正文是体。email 模块负责把内容组装成合规的邮件对象,smtplib 负责把它通过 SMTP 服务器发出去:

import os, smtplib
from email.mime.text import MIMEText

msg = MIMEText("今日数据已生成", "plain", "utf-8")
msg["Subject"] = "每日报表"
msg["From"] = os.environ["MAIL_USER"]
msg["To"] = "boss@example.com"

with smtplib.SMTP(os.environ["MAIL_HOST"], 587) as s:
    s.starttls()
    s.login(os.environ["MAIL_USER"], os.environ["MAIL_PASS"])
    s.send_message(msg)

MIMEText 第一个参数是正文,“plain” 表示纯文本,“utf-8” 是编码。with 语句管连接,退出自动关。端口和加密方式要对应:25 是传统明文端口(基本不用了);587 是提交端口,连上后 starttls() 升级成加密;465 是 SSL 端口,得用 smtplib.SMTP_SSL 而不是 SMTP。多数现代邮箱用 587+starttls。

二、加附件

附件用 MIMEMultipart 当容器,正文和附件各是一"块"分别 attach 进去:

from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication

msg = MIMEMultipart()
msg["Subject"] = "每日报表"
msg.attach(MIMEText("见附件", "plain", "utf-8"))

with open("report.xlsx", "rb") as f:
    part = MIMEApplication(f.read())
    part.add_header("Content-Disposition", "attachment", filename="report.xlsx")
    msg.attach(part)

MIMEMultipart 没有正文不行,所以先 attach 一段 MIMEText 当正文;附件读二进制,MIMEApplication 按"应用类型"包起来,add_header 的 Content-Disposition 告诉邮件客户端显示的文件名。要发多个附件就 open 多次、attach 多次。中文文件名在部分客户端会乱码,需要再对 filename 做 RFC 2231 编码(email 模块有 header 相关的处理),或者干脆用英文文件名最稳。

三、想发 HTML 正文

把 MIMEText 的 “plain” 换成 “html”,正文就能写带样式的 HTML,适合做得好看一点的报告:

msg = MIMEText("<h3>今日数据</h3><p>已完成</p>", "html", "utf-8")

配合 MIMEMultipart 时,正文块用 html 版、附件照加,就是一封带排版的带附件邮件。

四、几个要注意的点

第一,密码走环境变量(os.environ)别写死代码里,不然代码一进 git 凭据就泄露了。
第二,很多邮箱(Gmail、QQ、163)SMTP 不让用登录密码,要去邮箱设置里开"SMTP/IMAP"再拿一个专用"授权码"当密码用。
第三,频繁发会被服务商限流甚至判垃圾邮件,控制发送频率、用固定发件域名能降风险。
第四,生产环境别用个人邮箱发批量通知,用事务邮件服务(如 SendGrid、阿里云邮件推送)更稳、还能看送达率。
第五,send_message 抛异常要 try/catch,连不上、认证失败都得有处理,别让定时任务静默失败。

五、小结

发邮件用标准库 smtplib 就够:MIMEText 发纯文本(或 html 排版),要附件换 MIMEMultipart 把文件和正文都 attach,MIMEApplication 包二进制。端口按加密方式选 465(SSL) 或 587(starttls),密码走环境变量、邮箱服务商要授权码。挂上定时任务就能每日自动发,异常记得接住别静默失败。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。