在使用 Python 的 smtplib 发送邮件时,你需要连接到邮件服务器的 SMTP 端口,最常用的端口是:

587(Submission):最推荐,用于邮件提交,支持 STARTTLS,意味着连接开始时是普通的明文,然后通过starttls()方法升级为加密连接,这是现代邮件客户端和服务器最普遍和安全的做法。465(SMTPS):传统上用于 SMTP over SSL/TLS,这是一个加密的端口,连接建立后立即开始加密通信,虽然现在很多服务仍支持它,但587+STARTTLS是更现代的标准。25(SMTP):标准的 SMTP 端口,通常用于服务器到服务器的邮件中继,许多公共邮件服务(如 Gmail, Outlook)已禁止从客户端(如你的家庭电脑或服务器)直接使用端口25发送邮件,以防止垃圾邮件。
不同端口的详细用法与代码示例
端口 587 (推荐使用)
这是目前最主流、最安全的发送邮件方式,流程如下:
- 连接到服务器的 587 端口。
- 使用
ehlo()命令问候服务器。 - 发送
starttls()命令,将连接升级为加密的 TLS 连接。 - (可选但推荐)再次使用
ehlo()命令,因为 TLS 升级后服务器可能会通告新的功能。 - 登录。
- 发送邮件。
import smtplib
from email.mime.text import MIMEText
from email.utils import formataddr
msg = MIMEText('这是一封使用 smtplib 和端口 587 发送的测试邮件。', 'plain', 'utf-8')
msg['From'] = formataddr(['发件人昵称', 'your_email@example.com'])
msg['To'] = formataddr(['收件人昵称', 'recipient_email@example.com'])
msg['Subject'] = '测试邮件 - 端口 587'
# 邮件服务器配置
# 请替换为你的真实邮箱服务器地址和凭据
smtp_server = 'smtp.example.com' # smtp.gmail.com
smtp_port = 587
sender_email = 'your_email@example.com'
password = 'your_password' # 注意:对于 Gmail 等,可能需要使用“应用专用密码”
try:
# 1. 创建 SMTP 对象并连接到服务器
# 使用 with 语句可以确保连接正确关闭
with smtplib.SMTP(smtp_server, smtp_port) as server:
# 2. 设置调试模式(可选,可以看到详细的通信过程)
server.set_debuglevel(1)
# 3. 发送 EHLO 命令
server.ehlo()
# 4. 启用 TLS 加密
server.starttls()
# 5. EHLO 命令(TLS 升级后建议再次发送)
server.ehlo()
# 6. 登录
server.login(sender_email, password)
# 7. 发送邮件
# 注意:sendmail 的第二个参数是收件人列表
server.sendmail(sender_email, ['recipient_email@example.com'], msg.as_string())
print("邮件发送成功!")
except smtplib.SMTPAuthenticationError:
print("认证失败,请检查邮箱地址和密码。")
except smtplib.SMTPConnectError:
print("连接服务器失败,请检查服务器地址和端口。")
except smtplib.SMTPException as e:
print(f"邮件发送失败,错误: {e}")
except Exception as e:
print(f"发生未知错误: {e}")
端口 465 (传统方式)
这个端口直接建立 SSL/TLS 加密连接,在 Python 中,你需要使用 SMTP_SSL 类,而不是 SMTP。
import smtplib
from email.mime.text import MIMEText
from email.utils import formataddr
msg = MIMEText('这是一封使用 smtplib 和端口 465 发送的测试邮件。', 'plain', 'utf-8')
msg['From'] = formataddr(['发件人昵称', 'your_email@example.com'])
msg['To'] = formataddr(['收件人昵称', 'recipient_email@example.com'])
msg['Subject'] = '测试邮件 - 端口 465'
# 邮件服务器配置
smtp_server = 'smtp.example.com' # smtp.gmail.com
smtp_port = 465
sender_email = 'your_email@example.com'
password = 'your_password'
try:
# 1. 使用 SMTP_SSL 直接建立加密连接
with smtplib.SMTP_SSL(smtp_server, smtp_port) as server:
# 2. 设置调试模式(可选)
server.set_debuglevel(1)
# 3. 登录(注意:在 SSL 连接建立后直接登录)
server.login(sender_email, password)
# 4. 发送邮件
server.sendmail(sender_email, ['recipient_email@example.com'], msg.as_string())
print("邮件发送成功!")
except smtplib.SMTPAuthenticationError:
print("认证失败,请检查邮箱地址和密码。")
except smtplib.SMTPConnectError:
print("连接服务器失败,请检查服务器地址和端口。")
except smtplib.SMTPException as e:
print(f"邮件发送失败,错误: {e}")
except Exception as e:
print(f"发生未知错误: {e}")
主流邮件服务商的 SMTP 端口配置
为了方便你参考,这里是一些常用邮箱服务商的配置信息:
| 邮件服务商 | SMTP 服务器地址 | 推荐端口 | 加密方式 | 备注 |
|---|---|---|---|---|
| Gmail | smtp.gmail.com |
587 |
STARTTLS |
需要开启“两步验证”并生成“应用专用密码”。 |
465 |
SSL/TLS |
同样需要应用专用密码。 | ||
| Outlook / Hotmail | smtp.office365.com |
587 |
STARTTLS |
推荐使用此配置。 |
465 |
SSL/TLS |
也可用。 | ||
| QQ邮箱 | smtp.qq.com |
587 |
STARTTLS |
需要开启“SMTP服务”并获取授权码。 |
465 |
SSL/TLS |
也可用。 | ||
| 163邮箱 | smtp.163.com |
587 |
STARTTLS |
需要开启“客户端授权密码”。 |
465 |
SSL/TLS |
也可用。 | ||
| 阿里云企业邮箱 | smtp.mxhichina.com |
465 |
SSL/TLS |
官方推荐使用 465 端口。 |
总结与最佳实践
- 首选端口 587:除非有特殊要求,否则总是优先尝试使用端口
587和STARTTLS,这是业界公认的最佳实践。 - 查阅官方文档:如果你不确定某个邮箱服务商的正确配置,请务必查阅其官方的帮助文档或设置指南。
- 使用 SSL 上下文(高级):对于更高级的安全需求,可以在
starttls()或SMTP_SSL中传入一个ssl.SSLContext对象,以指定更严格的 TLS 版本和证书验证,这可以防止某些中间人攻击。import ssl # ... context = ssl.create_default_context() server.starttls(context=context) # 或者 # with smtplib.SMTP_SSL(smtp_server, smtp_port, context=context) as server:
- 处理异常:网络和服务器配置都可能出错,务必使用
try...except块来捕获smtplib可能抛出的异常,使你的程序更健壮。 - 安全性:不要在代码中硬编码你的邮箱密码,对于生产环境,应该使用环境变量、配置文件或密钥管理服务来存储敏感信息,对于像 Gmail 这样的服务,使用“应用专用密码”而不是你的主密码。

