📧 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 前置准备
- 登录 QQ 邮箱 → 设置 → 账号
- 开启 POP3/SMTP服务
- 生成 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 |
添加附件内容 |

浙公网安备 33010602011771号