使用Python发送电子邮件的步骤和流程总结如下:
第一节 步骤和流程概述
一、核心步骤
-
准备SMTP参数
-
发件人邮箱(需开启SMTP服务)
-
SMTP授权码(非邮箱登录密码)
-
收件人地址(支持单个字符串或列表)
-
SMTP服务器地址和端口(根据加密方式选择)
-
明文+STARTTLS:端口25/587 → 使用
SMTP
类 +starttls()
-
SSL/TLS:端口465 → 使用
SMTP_SSL
类
-
-
-
构建邮件内容
-
使用
MIMEText
创建邮件正文(纯文本) -
设置邮件头:
msg['Subject'] = "邮件主题" # 主题 msg['From'] = sender # 发件人 msg['To'] = ", ".join(receiver) # 收件人(显示用)
-
-
创建SMTP连接
# 方式1:STARTTLS加密(端口25/587) with smtplib.SMTP(smtp_server, smtp_port, timeout=10) as server: server.starttls() # 启用加密 server.login(sender, auth_code) # 方式2:SSL加密(端口465) with smtplib.SMTP_SSL(smtp_server, smtp_port, timeout=10) as server: server.login(sender, auth_code)
-
身份认证
server.login(sender, auth_code) # 使用授权码认证
-
发送邮件
server.sendmail(sender, receiver, msg.as_string())
二、安全注意事项
-
强制加密传输
-
始终使用SSL/TLS(通过
SMTP_SSL
或starttls()
)。
-
-
敏感信息保护
-
关闭调试日志(
server.set_debuglevel(0)
)。 -
避免在日志中输出授权码或邮箱地址。
-
-
异常处理
-
捕获关键异常:
-
SMTPAuthenticationError
(认证失败) -
SMTPConnectError
(连接失败) -
通用
SMTPException
兜底。
-
-
三、代码差异对比
特性 | 代码1(端口25) | 代码2(端口465) |
---|---|---|
加密方式 | 先明文连接,后 starttls() | 直接建立SSL连接 |
适用场景 | 支持STARTTLS的服务器 | 仅支持SSL的服务器 |
实现类 | smtplib.SMTP | smtplib.SMTP_SSL |
默认端口 | 25 | 465 |
四、完整流程示意图
复制
准备参数 → 构建邮件 → 建立加密连接 → 登录认证 → 发送 → 处理异常
五、扩展建议
-
证书验证
添加SSL上下文验证服务器证书(增强安全性):import ssl context = ssl.create_default_context() server = smtplib.SMTP_SSL(..., context=context)
-
多收件人处理
msg['To']
仅用于显示,实际收件人列表需在sendmail()
中传入。 -
支持HTML邮件
使用MIMEMultipart
和MIMEText
的html
类型:msg = MIMEText(content, 'html', 'utf-8')
通过遵循上述步骤,可安全、高效地实现Python邮件发送功能。
第二节 代码示例
以下是标注了发送步骤和流程的代码:
代码1(使用SMTP+STARTTLS加密)
# 步骤1:建立SMTP连接(明文)
with smtplib.SMTP(smtp_server, smtp_port, timeout=10) as server:
# 步骤2:启用TLS加密传输
server.starttls()
# 安全设置:关闭调试日志
server.set_debuglevel(0)
# 步骤3:身份认证
server.login(sender, auth_code)
# 步骤4:构建邮件内容
msg = MIMEText(content, 'plain', 'utf-8') # 创建纯文本邮件
msg['Subject'] = subject # 设置主题
msg['From'] = sender # 设置发件人
msg['To'] = ', '.join(receiver) if isinstance(receiver, list) else receiver # 设置收件人(显示用)
# 步骤5:发送邮件
server.sendmail(sender, receiver, msg.as_string()) # 实际发送(收件人参数为列表)
代码2(使用SMTP_SSL加密)
# 步骤1:建立SMTP_SSL加密连接
with smtplib.SMTP_SSL(smtp_server, smtp_port, timeout=10) as server:
# 安全设置:关闭调试日志
server.set_debuglevel(0)
# 步骤2:身份认证
server.login(sender, auth_code)
# 步骤3:构建邮件内容
msg = MIMEText(content, 'plain', 'utf-8') # 创建纯文本邮件
msg['Subject'] = subject # 设置主题
msg['From'] = sender # 设置发件人
msg['To'] = ', '.join(receiver) if isinstance(receiver, list) else receiver # 设置收件人(显示用)
# 步骤4:发送邮件
server.sendmail(sender, receiver, msg.as_string()) # 实际发送(收件人参数为列表)
关键流程对比
步骤 | 代码1(SMTP+STARTTLS) | 代码2(SMTP_SSL) |
---|---|---|
连接方式 | 先明文连接,后通过 starttls() 加密 | 直接建立SSL加密连接 |
加密时机 | 连接后手动启用加密 | 连接时自动加密 |
必要端口 | 25/587 | 465 |
适用场景 | 服务器支持STARTTLS升级 | 服务器仅支持SSL |
补充说明
-
msg['To']
的特殊性-
该字段仅为邮件显示用,实际收件人由
sendmail()
的receiver
参数控制 -
允许多个收件人用列表传入(如
["a@x.com", "b@y.com"]
)
-
-
安全差异
-
代码1的
starttls()
需要服务器支持协议升级 -
代码2的
SMTP_SSL
强制全程加密,更推荐用于高安全场景
-
-
上下文管理器
-
with
语句自动处理连接的关闭,避免资源泄漏
-