Python SMTP发送邮件(一文讲透)
💡一则或许对你有用的小广告
欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论
- 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于
Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...
,点击查看项目介绍 ;演示链接: http://116.62.199.48:7070 ;- 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;
截止目前, 星球 内专栏累计输出 90w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 3100+ 小伙伴加入学习 ,欢迎点击围观
前言
在数字化时代,邮件仍然是最高效的信息传递工具之一。无论是自动化报告、用户通知还是团队协作,编程实现邮件发送都能显著提升工作效率。Python 作为一门简洁且功能强大的语言,提供了丰富的库来简化这一任务。本文将深入讲解如何通过 Python SMTP 发送邮件,从协议基础到代码实战,帮助开发者快速掌握这一技能。
SMTP 协议:邮件传输的“邮局系统”
SMTP(Simple Mail Transfer Protocol)是互联网标准协议,负责在邮件服务器之间传递邮件。想象 SMTP 是一个“邮局系统”:
- 发件人(如 Python 程序)将邮件交给 SMTP 服务器(邮局);
- SMTP 服务器负责将邮件路由到 收件人服务器(如 Gmail、QQ 邮箱的服务器);
- 最终,收件人的邮箱会收到邮件。
关键概念
- SMTP 服务器地址:不同邮箱提供商的 SMTP 地址不同(例如 Gmail 的 SMTP 是
smtp.gmail.com
)。 - 端口号:常用端口包括 25(普通连接)、465(SSL 加密)和 587(TLS 加密)。
- 身份验证:需提供邮箱账号和授权码(非登录密码,部分邮箱需开启“允许第三方登录”)。
Python 实现 SMTP 发送邮件的步骤
Python 的 smtplib
模块是实现邮件发送的核心工具。以下是分步指南:
1. 安装依赖库
大多数 Python 环境已内置 smtplib
,但若需处理邮件内容(如 HTML 或附件),还需 email
模块:
pip install email
2. 建立 SMTP 连接
使用 smtplib.SMTP()
或 smtplib.SMTP_SSL()
创建连接:
import smtplib
server = smtplib.SMTP("smtp.example.com", 587)
server.starttls() # 启用 TLS 加密
server_ssl = smtplib.SMTP_SSL("smtp.example.com", 465)
3. 登录 SMTP 服务器
通过邮箱账号和授权码登录:
server.login("your_email@example.com", "your_authorization_code")
4. 编写邮件内容
使用 email
模块构造邮件对象:
from email.mime.text import MIMEText
message = MIMEText("Hello, this is a test email!", "plain", "utf-8")
message["Subject"] = "Test Email"
message["From"] = "your_email@example.com"
message["To"] = "recipient@example.com"
5. 发送并关闭连接
调用 sendmail()
发送邮件,最后关闭连接:
server.sendmail(
from_addr="your_email@example.com",
to_addrs=["recipient@example.com"],
msg=message.as_string()
)
server.quit()
完整示例:发送普通文本邮件
以下是一个完整的代码示例,展示如何发送纯文本邮件:
import smtplib
from email.mime.text import MIMEText
smtp_server = "smtp.example.com"
smtp_port = 587
smtp_user = "your_email@example.com"
smtp_password = "your_authorization_code"
server = smtplib.SMTP(smtp_server, smtp_port)
server.starttls()
try:
server.login(smtp_user, smtp_password)
message = MIMEText("你好!这是一封测试邮件。", "plain", "utf-8")
message["Subject"] = "Python SMTP 测试"
message["From"] = smtp_user
message["To"] = "recipient@example.com"
server.sendmail(
smtp_user,
["recipient@example.com"],
message.as_string()
)
print("邮件发送成功!")
except Exception as e:
print(f"发送失败:{str(e)}")
finally:
server.quit()
进阶技巧:发送 HTML 邮件和附件
发送 HTML 格式邮件
通过 MIMEText
的 html
参数和嵌入 CSS 样式:
from email.mime.multipart import MIMEMultipart
html_content = """
<html>
<body>
<h1>欢迎使用 Python SMTP!</h1>
<p>这是一封 <strong>HTML 格式</strong>的邮件。</p>
<img src="cid:logo_image">
</body>
</html>
"""
message = MIMEMultipart("alternative")
message.attach(MIMEText(html_content, "html"))
from email.mime.image import MIMEImage
with open("logo.png", "rb") as f:
img = MIMEImage(f.read())
img.add_header("Content-ID", "<logo_image>")
message.attach(img)
添加附件
使用 MIMEApplication
或 MIMEBase
处理文件:
from email.mime.application import MIMEApplication
with open("report.pdf", "rb") as f:
attachment = MIMEApplication(f.read(), _subtype="pdf")
attachment.add_header(
"Content-Disposition",
"attachment",
filename="report.pdf"
)
message.attach(attachment)
常见问题与解决方案
1. 连接超时或拒绝
原因:SMTP 服务器未正确配置端口或防火墙拦截。
解决:
- 确认端口(如 Gmail 的端口 587 需启用 TLS);
- 在服务器防火墙中开放对应端口。
2. 登录失败
原因:授权码错误或未开启“允许第三方登录”。
解决:
- 通过邮箱提供商官网生成授权码;
- 在邮箱设置中启用“IMAP/SMTP 服务”或“允许低安全应用”。
3. 邮件被标记为垃圾邮件
原因:发件人域名未通过 SPF/DKIM 验证。
解决:
- 配置邮箱服务器的 SPF 记录;
- 在邮件正文中添加明确的退订链接。
实战案例:自动化发送日报邮件
假设需要每日向团队发送项目进度报告,代码如下:
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from datetime import datetime
smtp_server = "smtp.gmail.com"
smtp_port = 587
smtp_user = "your_gmail@gmail.com"
smtp_password = "your_app_password"
today = datetime.now().strftime("%Y-%m-%d")
message = MIMEMultipart()
message["Subject"] = f"项目日报 {today}"
message["From"] = smtp_user
message["To"] = "team@example.com"
html_body = f"""
<p>尊敬的团队成员:</p>
<p>以下是 {today} 的项目进展:</p>
<ul>
<li>功能 A 已完成 80%</li>
<li>测试报告已上传至附件</li>
</ul>
<p>祝好,<br>自动化系统</p>
"""
message.attach(MIMEText(html_body, "html"))
with open("daily_report.pdf", "rb") as f:
attachment = MIMEApplication(f.read(), _subtype="pdf")
attachment.add_header(
"Content-Disposition",
"attachment",
filename=f"daily_report_{today}.pdf"
)
message.attach(attachment)
try:
with smtplib.SMTP(smtp_server, smtp_port) as server:
server.starttls()
server.login(smtp_user, smtp_password)
server.sendmail(smtp_user, ["team@example.com"], message.as_string())
print("日报发送成功!")
except Exception as e:
print(f"发送失败:{str(e)}")
总结
通过本文的讲解,读者应能掌握 Python SMTP 发送邮件的核心流程,包括协议原理、代码实现和常见问题处理。从基础的文本邮件到进阶的 HTML 与附件,开发者可根据实际需求灵活调整。
SMTP 的强大之处在于其标准化的传输机制,结合 Python 的简洁语法,能快速构建自动化通知系统、用户验证或数据分析报告工具。建议读者通过以下步骤进一步实践:
- 尝试修改代码,发送包含图片或复杂表格的邮件;
- 集成到现有项目中,例如结合定时任务实现每日提醒;
- 探索第三方库(如
yagmail
)的简化用法。
掌握这一技能后,邮件将成为开发者手中又一个高效的信息传递工具,助力提升工作效率与自动化水平。