Python SMTP发送邮件(一文讲透)

更新时间:

💡一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

截止目前, 星球 内专栏累计输出 90w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 3100+ 小伙伴加入学习 ,欢迎点击围观

前言

在数字化时代,邮件仍然是最高效的信息传递工具之一。无论是自动化报告、用户通知还是团队协作,编程实现邮件发送都能显著提升工作效率。Python 作为一门简洁且功能强大的语言,提供了丰富的库来简化这一任务。本文将深入讲解如何通过 Python SMTP 发送邮件,从协议基础到代码实战,帮助开发者快速掌握这一技能。


SMTP 协议:邮件传输的“邮局系统”

SMTP(Simple Mail Transfer Protocol)是互联网标准协议,负责在邮件服务器之间传递邮件。想象 SMTP 是一个“邮局系统”:

  • 发件人(如 Python 程序)将邮件交给 SMTP 服务器(邮局);
  • SMTP 服务器负责将邮件路由到 收件人服务器(如 Gmail、QQ 邮箱的服务器);
  • 最终,收件人的邮箱会收到邮件。

关键概念

  1. SMTP 服务器地址:不同邮箱提供商的 SMTP 地址不同(例如 Gmail 的 SMTP 是 smtp.gmail.com)。
  2. 端口号:常用端口包括 25(普通连接)、465(SSL 加密)和 587(TLS 加密)。
  3. 身份验证:需提供邮箱账号和授权码(非登录密码,部分邮箱需开启“允许第三方登录”)。

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 格式邮件

通过 MIMETexthtml 参数和嵌入 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)

添加附件

使用 MIMEApplicationMIMEBase 处理文件:

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 的简洁语法,能快速构建自动化通知系统、用户验证或数据分析报告工具。建议读者通过以下步骤进一步实践:

  1. 尝试修改代码,发送包含图片或复杂表格的邮件;
  2. 集成到现有项目中,例如结合定时任务实现每日提醒;
  3. 探索第三方库(如 yagmail)的简化用法。

掌握这一技能后,邮件将成为开发者手中又一个高效的信息传递工具,助力提升工作效率与自动化水平。

最新发布