news 2026/8/5 18:45:35

Day 43:【99天精通Python】发送邮件 (smtplib) - 你的自动化信使

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Day 43:【99天精通Python】发送邮件 (smtplib) - 你的自动化信使

Day 43:【99天精通Python】发送邮件 (smtplib) - 你的自动化信使

前言

欢迎来到第43天!

在前面的课程中,我们学会了写爬虫、做数据分析、处理 Excel 和图片。当这些自动化任务运行结束后,我们通常希望第一时间收到通知,比如:

  • 爬虫抓到了新的优惠信息,发邮件提醒我。
  • 每天凌晨 2 点自动备份数据库,并把日志文件发给运维。
  • 监控股票价格,跌破止损线时发警报。

虽然现在微信、钉钉通知很流行,但邮件依然是职场中最正式、最通用的通知方式。Python 内置的smtplibemail模块,可以让我们轻松实现邮件的自动发送。

本节内容:

  • 邮件发送原理 (SMTP)
  • 准备工作:获取授权码
  • 发送纯文本邮件
  • 发送 HTML 富文本邮件
  • 发送带附件的邮件
  • 封装成通用的邮件工具类

一、邮件发送原理

发送邮件就像寄信,需要两个核心要素:

  1. 信封和信纸:由email模块负责,构建邮件的标题、正文、附件等格式。
  2. 邮局:由smtplib模块负责,通过SMTP (Simple Mail Transfer Protocol)协议将邮件发给邮件服务器(如 QQ 邮箱服务器、网易邮箱服务器)。

注意:接收邮件通常使用 POP3 或 IMAP 协议,但今天我们只讲发送。


二、准备工作:开启 SMTP 服务

出于安全考虑,现代邮箱不允许直接使用登录密码在代码中发邮件,必须使用授权码 (Authorization Code)

QQ 邮箱为例(163/Gmail 类似):

  1. 登录网页版 QQ 邮箱。
  2. 点击设置->账户
  3. 找到POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务
  4. 开启POP3/SMTP服务
  5. 按照提示发送短信验证,获取一串字符(如abcdefghijklmn),这就是授权码

常用 SMTP 服务器配置

邮箱SMTP 服务器SSL 端口 (推荐)非 SSL 端口
QQsmtp.qq.com46525
163smtp.163.com46525
Gmailsmtp.gmail.com465587 (TLS)

三、发送第一封纯文本邮件

importsmtplibfromemail.mime.textimportMIMETextfromemail.headerimportHeader# --- 配置信息 ---mail_host="smtp.qq.com"# SMTP 服务器mail_port=465# SSL 端口mail_user="123456789@qq.com"# 你的邮箱账号mail_pass="xxxxxxxxxxxx"# 你的授权码 (不是密码!)sender="123456789@qq.com"# 发件人receivers=["friend@example.com"]# 收件人列表# --- 1. 构建邮件内容 ---# MIMEText(内容, 类型, 编码)message=MIMEText("你好!这是我用 Python 发送的第一封邮件。","plain","utf-8")message['From']=Header("Python助手",'utf-8')# 发件人昵称message['To']=Header("亲爱的朋友",'utf-8')# 收件人昵称message['Subject']=Header("Python 邮件测试",'utf-8')# 邮件标题# --- 2. 发送邮件 ---try:# 使用 SSL 加密连接 (推荐)smtp_obj=smtplib.SMTP_SSL(mail_host,mail_port)# 登录smtp_obj.login(mail_user,mail_pass)# 发送smtp_obj.sendmail(sender,receivers,message.as_string())print("邮件发送成功!")smtp_obj.quit()# 退出exceptsmtplib.SMTPExceptionase:print(f"邮件发送失败:{e}")

四、发送 HTML 格式邮件

纯文本太丑了,没法加粗、变色或插图。我们可以发送HTML格式的邮件。
只需要将MIMEText的第二个参数从"plain"改为"html"

html_content=""" <h1>每日数据报告</h1> <p>亲爱的用户:</p> <p>今天的任务 <span style="color:green; font-weight:bold;">执行成功</span>。</p> <table border="1"> <tr> <th>项目</th> <th>数值</th> </tr> <tr> <td>新增用户</td> <td>1024</td> </tr> </table> <p><a href="https://www.python.org">点击查看详情</a></p> """message=MIMEText(html_content,"html","utf-8")message['Subject']=Header("今日日报 (HTML版)",'utf-8')# ... 发送逻辑同上 ...

五、发送带附件的邮件

附件稍微复杂一点,需要创建一个MIMEMultipart对象(像一个大包裹),然后把正文(MIMEText)和附件(MIMEApplication)都塞进去。

importsmtplibfromemail.mime.textimportMIMETextfromemail.mime.multipartimportMIMEMultipartfromemail.mime.applicationimportMIMEApplication# 专门处理文件fromemail.headerimportHeaderdefsend_email_with_attachment():# ... 配置信息 (同上) ...# 1. 创建一个带附件的实例message=MIMEMultipart()message['From']=Header("Python助手",'utf-8')message['To']=Header("Boss",'utf-8')message['Subject']=Header("附带报表文件",'utf-8')# 2. 添加正文message.attach(MIMEText("附件是今天的销售报表,请查收。","plain","utf-8"))# 3. 添加附件file_path="report.xlsx"# 假设本地有这个文件try:withopen(file_path,"rb")asf:# 读取文件内容part=MIMEApplication(f.read())# 添加头信息,设置文件名part.add_header('Content-Disposition','attachment',filename="report.xlsx")# 将附件添加到邮件中message.attach(part)exceptFileNotFoundError:print("附件文件未找到!")return# 4. 发送try:server=smtplib.SMTP_SSL(mail_host,mail_port)server.login(mail_user,mail_pass)server.sendmail(sender,receivers,message.as_string())server.quit()print("带附件邮件发送成功!")exceptExceptionase:print(f"发送失败:{e}")

六、封装:EmailSender 类

为了在以后的项目中方便复用,我们把这些逻辑封装成一个类。

classEmailSender:def__init__(self,host,user,password,port=465):self.host=host self.user=user self.password=password self.port=portdefsend(self,to_list,subject,content,files=None):""" :param to_list: 收件人列表 ["a@qq.com", "b@163.com"] :param subject: 标题 :param content: 正文 (支持HTML) :param files: 附件路径列表 ["a.jpg", "b.xlsx"] """message=MIMEMultipart()message['From']=Header(self.user)message['To']=Header(",".join(to_list))message['Subject']=Header(subject,'utf-8')# 添加正文message.attach(MIMEText(content,'html','utf-8'))# 添加附件iffiles:forfile_pathinfiles:try:withopen(file_path,"rb")asf:part=MIMEApplication(f.read())filename=file_path.split("/")[-1]# 获取文件名part.add_header('Content-Disposition','attachment',filename=filename)message.attach(part)exceptExceptionase:print(f"附件{file_path}加载失败:{e}")# 发送try:server=smtplib.SMTP_SSL(self.host,self.port)server.login(self.user,self.password)server.sendmail(self.user,to_list,message.as_string())server.quit()returnTrueexceptExceptionase:print(f"发送出错:{e}")returnFalse# 使用示例# sender = EmailSender("smtp.qq.com", "my@qq.com", "auth_code")# sender.send(["boss@qq.com"], "测试", "<h1>Hello</h1>", ["data.xlsx"])

七、常见问题

Q1:报错535 Login Fail. Please enter your authorization code

这是最常见的错误。你用了邮箱登录密码,或者授权码过期了。请去邮箱设置里重新生成一个授权码

Q2:报错ConnectionRefusedError(端口问题)

  • 默认端口 25 经常被云服务器厂商(如阿里云、腾讯云)封禁,防止垃圾邮件。
  • 解决方法:始终使用SMTP_SSL465端口。

Q3:邮件被识别为垃圾邮件?

  • 标题不要太短或包含敏感词。
  • 不要只发一个链接或图片,多写点正文。
  • 不要频繁给同一个邮箱发同样的测试邮件。

八、小结

邮件发送

配置 SMTP

构建邮件

发送过程

开启服务 (POP3/SMTP)

获取授权码 (非密码)

服务器地址 (smtp.qq.com)

MIMEText (纯文本/HTML)

MIMEMultipart (混合)

MIMEApplication (附件)

conn = SMTP_SSL(host, 465)

conn.login(user, code)

conn.sendmail(...)

关键要点

  1. 授权码是关键,千万别用密码。
  2. MIMEMultipart是容器,文本和附件往里塞。
  3. 推荐封装成类,以后只要一行代码就能发邮件。

九、课后作业

  1. 每日天气推送:结合 Requests (Day 27) 获取天气 API,Schedule (Day 41) 定时任务,每天早上 8 点给自己发一封带有今天天气预报的邮件。
  2. 爬虫监控:编写一个脚本监控某个网页(如商品价格),当价格低于预期时,自动发送邮件报警。
  3. 群发工资条 (挑战):读取一个 Excel 表格(包含:姓名、邮箱、工资),遍历表格,给每个人发送一封属于他自己的工资条邮件。

下节预告

Day 44:操作 PDF (PyPDF2)- Word 和 Excel 我们都搞定了,怎么能少了 PDF?明天我们学习如何用 Python 合并、拆分 PDF,甚至提取里面的文字。


系列导航

  • 上一篇:Day 42 - 图像处理Pillow
  • 下一篇:Day 44 - 操作PDFPyPDF2(待更新)
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/5 16:38:29

fft npainting lama图像修复系统ARM架构:树莓派等设备可行性测试

fft npainting lama图像修复系统ARM架构&#xff1a;树莓派等设备可行性测试 1. 引言 随着边缘计算和嵌入式AI应用的快速发展&#xff0c;将图像修复类深度学习模型部署到低功耗、低成本的ARM架构设备&#xff08;如树莓派&#xff09;上成为一项具有实际价值的技术探索。本文…

作者头像 李华
网站建设 2026/8/5 3:10:56

迎接充电基础设施“新规范”,如何用一套系统实现全网智能管理?

安科瑞刘鸿鹏172 一 ⑥⑨⑦② 一 5322摘要随着工业用电规模的持续扩大&#xff0c;中压配电系统在保障企业连续生产中的重要性日益凸显。开关柜作为工业配电系统的关键节点&#xff0c;其内部绝缘状态直接影响供电安全与运行可靠性。局部放电作为绝缘劣化的早期表现形式&#x…

作者头像 李华
网站建设 2026/7/30 17:04:36

OpenDataLab MinerU避坑指南:常见问题全解答

OpenDataLab MinerU避坑指南&#xff1a;常见问题全解答 1. 引言 在当前AI驱动的文档智能处理场景中&#xff0c;OpenDataLab/MinerU2.5-2509-1.2B 模型凭借其轻量级架构和专业化的文档理解能力&#xff0c;成为众多开发者与企业的首选工具。该模型基于 InternVL 架构&#x…

作者头像 李华
网站建设 2026/7/31 11:16:46

AMD Ryzen处理器调试终极指南:全面解锁硬件性能潜力

AMD Ryzen处理器调试终极指南&#xff1a;全面解锁硬件性能潜力 【免费下载链接】SMUDebugTool A dedicated tool to help write/read various parameters of Ryzen-based systems, such as manual overclock, SMU, PCI, CPUID, MSR and Power Table. 项目地址: https://gitc…

作者头像 李华
网站建设 2026/7/31 7:19:20

Qwen3-32B极速体验:5分钟从注册到对话,不装环境

Qwen3-32B极速体验&#xff1a;5分钟从注册到对话&#xff0c;不装环境 你是不是也遇到过这样的情况&#xff1a;产品发布会马上就要开始了&#xff0c;领导突然说“加个AI互动环节”&#xff0c;技术同事却临时请假&#xff0c;整个团队陷入慌乱&#xff1f;别急——今天我要…

作者头像 李华
网站建设 2026/7/31 10:58:59

Legacy iOS Kit完全指南:让老款苹果设备重获新生的终极工具链

Legacy iOS Kit完全指南&#xff1a;让老款苹果设备重获新生的终极工具链 【免费下载链接】Legacy-iOS-Kit An all-in-one tool to downgrade/restore, save SHSH blobs, and jailbreak legacy iOS devices 项目地址: https://gitcode.com/gh_mirrors/le/Legacy-iOS-Kit …

作者头像 李华