📧 Python SMTP发送邮件

一、概述

在 Python 中发送邮件主要通过 SMTP 协议 实现:

  • smtplib:Python 内置模块,用于连接邮件服务器、身份验证和发送邮件。
  • email:构建邮件内容(主题、正文、附件等)的模块。

二、基础协议知识

邮件发送涉及两种常见协议:

2.1 SSH(Secure Shell)

  • 用途:远程登录与操作服务器,非邮件相关,仅用于安全通信。
  • 通信端口:默认 22。
  • 应用场景:远程控制、文件传输等。

2.2 SMTP(Simple Mail Transfer Protocol)

  • 用途:发送邮件的标准协议(接收邮件需用 POP3 或 IMAP)。
  • 常见端口:
    • 25:明文传输(较旧,可能被禁用)
    • 465:SSL 加密
    • 587:TLS 加密

三、核心模块介绍

3.1 smtplib 模块(发送功能)

方法 作用
SMTP_SSL(server, port) 创建 SSL 加密连接
login(user, password) 登录邮箱
sendmail(from_addr, to_addrs, msg) 发送邮件
quit() 关闭连接

3.2 email 模块(构建内容)

3.2.1 文本/HTML正文

from email.mime.text import MIMEText

MIMEText(_text, _subtype='plain', _charset='utf-8')

# text:邮件正文内容。
# _subtype:内容类型,默认为 'plain'(纯文本),也可以设置为 'html'。
# _charset字符:编码,默认为 'us-ascii',通常设置为 'utf-8'。

3.2.2 多部分内容(含附件)

from email.mime.multipart import MIMEMultipart

MIMEMultipart(_subtype='mixed')

3.2.3 添加附件

from email.mime.application import MIMEApplication

MIMEApplication(file_data)
add_header('Content-Disposition', 'attachment', filename='文件名')

# Content-Disposition:指定要添加的头部字段名称。
# attachment:指定 Content-Disposition 的值,表示这是一个附件。
# filename:指定附件的文件名。

3.2.4 邮件头字段

字段 含义
['From'] 发件人邮箱
['To'] 收件人邮箱
['Subject'] 邮件主题
['Cc'] 抄送人
['Bcc'] 密送人

四、发送邮件完整流程(QQ → 网易)

4.1 前置准备

  1. 登录 QQ 邮箱 → 设置 → 账号
  2. 开启 POP3/SMTP服务
  3. 生成 16位授权码(用于登录)

4.2 简单发送示例

# 导入模块
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart

# 邮箱账号和授权码
smtp_server = 'smtp.qq.com'    # SMTP服务器地址,这里是QQ邮箱的
smtp_port = 465  			   # QQ邮箱SMTP服务的SSL端口号
sender = 'xxx@qq.com'  		   # 替换为你的邮箱账号
password = 'abcdefg23sdfasdf'  # 替换为你的授权码

# 收件人邮箱地址
to_addr = 'xxx@163.com'

# 创建邮件对象
msg = MIMEMultipart()
msg['From'] = sender
msg['To'] = to_addr
msg['Subject'] = '测试邮件主题'  # 邮件主题

# 添加邮件正文
text = MIMEText('这是一封测试邮件的正文内容', 'plain', 'utf-8')
msg.attach(text)

# 连接SMTP服务器并发送邮件
try:
    smtp = smtplib.SMTP_SSL(smtp_server, smtp_port)  # 使用SSL加密连接
    smtp.login(sender, password)  					 # 登录邮箱
    smtp.sendmail(sender, to_addr, msg.as_string())  # 发送邮件
    print('邮件发送成功!')
except Exception as e:
    print('发送失败:', e)
finally:
    smtp.quit()

五、进阶功能实现

5.1 添加附件(PDF/图片)

from email.mime.application import MIMEApplication

# 添加PDF
pdf = MIMEApplication(open('report.pdf', 'rb').read())
pdf.add_header('Content-Disposition', 'attachment', filename="报告.pdf")
msg.attach(pdf)

# 添加图片
img = MIMEApplication(open('photo.png', 'rb').read())
img.add_header('Content-ID', '<image1>')  # HTML 中引用 cid:image1
msg.attach(img)

5.2 HTML正文引用图片

<html>
  <body>
    <h1>截图展示</h1>
    <img src="cid:image1" width="500">
  </body>
</html>

src="cid:image1":cid 是内容 ID 的标识符,image1 是你为图片设置的唯一标识符。

5.3 群发邮件

receivers = ["user1@xx.com", "user2@xx.com"]
msg['To'] = ",".join(receivers)
smtp.sendmail(sender, receivers, msg.as_string())

5.4 抄送与密送

msg['Cc'] = "copy@xx.com"
msg['Bcc'] = "secret@xx.com"

提示:sendmail() 的第二个参数要包含所有接收者,包括 Cc 和 Bcc。


六、常见邮箱SMTP配置

邮箱类型 SMTP服务器地址 端口号 加密方式
QQ邮箱 smtp.qq.com 465 SSL
163邮箱 smtp.163.com 465 SSL
Gmail smtp.gmail.com 587 TLS

✅ Gmail 需在账户设置中开启“低安全性应用访问”


七、完整示例代码

import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.application import MIMEApplication

# 配置信息
smtp_server = "smtp.qq.com"
smtp_port = 465
sender = "your_email@qq.com"
auth_code = "授权码"
receivers = ["user1@xx.com", "user2@xx.com"]

# 构建邮件
msg = MIMEMultipart()
msg['Subject'] = "Python邮件测试"
msg['From'] = sender
msg['To'] = ",".join(receivers)
msg['Cc'] = "copy@xx.com"

# HTML 正文
html = """
<html>
  <body>
    <h2>测试邮件</h2>
    <p>这是一封 <b>Python</b> 发送的邮件</p>
    <img src="cid:image1">
  </body>
</html>
"""
msg.attach(MIMEText(html, "html", "utf-8"))

# 图片附件
with open("banner.png", "rb") as f:
    img = MIMEApplication(f.read())
    img.add_header('Content-ID', '<image1>')
    msg.attach(img)

# PDF附件
with open("report.pdf", "rb") as f:
    pdf = MIMEApplication(f.read())
    pdf.add_header('Content-Disposition', 'attachment', filename="报告.pdf")
    msg.attach(pdf)

# 发送邮件
try:
    smtp = smtplib.SMTP_SSL(smtp_server, smtp_port)
    smtp.login(sender, auth_code)
    all_receivers = receivers + [msg['Cc']]
    smtp.sendmail(sender, all_receivers, msg.as_string())
    print("邮件发送成功!")
except Exception as e:
    print("发送失败:", str(e))
finally:
    smtp.quit()

八、安全性建议

  • 避免硬编码敏感信息(如邮箱、授权码):
    • 可使用 .env 文件 + os.environ 读取。
  • 不要频繁发送邮件,避免被 SMTP 服务商封锁。
  • 测试前务必验证附件路径、格式正确。

九、总结

模块 功能
smtplib 连接服务器并发送邮件
email.mime.text 构建正文(纯文本/HTML)
email.mime.multipart 构建复杂邮件结构(正文 + 附件)
email.mime.application 添加附件内容
posted @ 2025-06-14 17:03  kyle_7Qc  阅读(129)  评论(0)    收藏  举报