smtplib 是 Python 提供的标准库,用于发送电子邮件。它通过 SMTP(简单邮件传输协议)与邮件服务器建立连接,并支持账号登录、加密传输、多收件人群发、HTML 格式及附件等多种邮件发送方式。与 email 模块搭配使用,可以实现强大的自动化邮件功能。
常见应用场景:
(1)用户注册时发送验证码或欢迎邮件。
(2)报警系统或日志服务的邮件通知。
(3)自动化任务(如数据分析、爬虫)的邮件汇报。
(4)后台定时任务推送日报或报告。
(5)内部消息系统发送提醒或通知。
◆ ◆ ◆
核心概念
1、SMTP 协议
即 Simple Mail Transfer Protocol,用于电子邮件的传输,通常端口号为 25、465(SSL)或 587(STARTTLS)。
2、SMTP 类
用于与 SMTP 服务器建立普通连接(非加密或支持 STARTTLS 加密)。
3、SMTP_SSL 类
用于直接通过 SSL 加密连接 SMTP 服务器,适用于需要高安全性的邮箱(如 Gmail、QQ 邮箱)。
4、登录认证
大多数邮箱服务器都需要身份验证,需提供发件人邮箱与授权码(非密码)。
5、邮件内容构造
通常与 email.mime 模块配合使用来构造邮件体,包括文本、HTML、附件等格式。
6、发件与收件
邮件通过 sendmail() 方法发送,需指定发件人、收件人列表和完整邮件内容字符串。
◆ ◆ ◆
应用举例
以下五个实例,全部采用显式连接、登录、发送、退出流程,并以 QQ 邮箱为例(你需替换为自己的真实邮箱和授权码)。
例 1:发送纯文本邮件(最基本用法)
import smtplib
from email.mime.text import MIMEText
from email.header import Header
sender = "your@qq.com"
password = "your_auth_code"
receiver = "receiver@example.com"
msg = MIMEText("这是一封来自 Python 的纯文本测试邮件。", "plain", "utf-8")
msg["Subject"] = Header("纯文本测试", "utf-8")
msg["From"] = Header(sender)
msg["To"] = Header(receiver)
smtp_server = "smtp.qq.com"
smtp_port = 465
server = smtplib.SMTP_SSL(smtp_server, smtp_port)
try:
server.login(sender, password)
server.sendmail(sender, [receiver], msg.as_string())
print("邮件发送成功")
except smtplib.SMTPException as e:
print("发送失败:", e)
finally:
try:
server.quit()
except:
pass例 2:发送 HTML 格式邮件
from email.mime.text import MIMEText
from email.header import Header
import smtplib
sender = "your@qq.com"
password = "your_auth_code"
receiver = "receiver@example.com"
html_content = """
Hello!
这是一封 HTML 格式 的测试邮件。
"""
msg = MIMEText(html_content, "html", "utf-8")
msg["Subject"] = Header("HTML 邮件测试", "utf-8")
msg["From"] = Header(sender)
msg["To"] = Header(receiver)
server = smtplib.SMTP_SSL("smtp.qq.com", 465)
try:
server.login(sender, password)
server.sendmail(sender, [receiver], msg.as_string())
print("HTML 邮件发送成功")
except smtplib.SMTPException as e:
print("发送失败:", e)
finally:
try:
server.quit()
except:
pass例 3:SSL 加密发送
from email.mime.text import MIMEText
from email.header import Header
import smtplib
sender = "your@qq.com"
password = "your_auth_code"
receiver = "receiver@example.com"
cc = "cc_user@example.com"
msg = MIMEText("邮件内容:这是带有抄送的邮件。", "plain", "utf-8")
msg["Subject"] = Header("抄送测试", "utf-8")
msg["From"] = Header(sender)
msg["To"] = Header(receiver)
msg["Cc"] = Header(cc)
server = smtplib.SMTP_SSL("smtp.qq.com", 465)
try:
server.login(sender, password)
# 注意:sendmail 的收件人列表必须包含所有收件人(包括抄送)
server.sendmail(sender, [receiver, cc], msg.as_string())
print("带抄送的邮件发送成功")
except smtplib.SMTPException as e:
print("发送失败:", e)
finally:
try:
server.quit()
except:
pass例 4:发送带附件的邮件(纯文本 + 附件)
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.application import MIMEApplication
from email.header import Header
sender = "your@qq.com"
password = "your_auth_code"
receiver = "receiver@example.com"
msg = MIMEMultipart()
msg["Subject"] = Header("带附件的邮件", "utf-8")
msg["From"] = Header(sender)
msg["To"] = Header(receiver)
# 邮件正文
msg.attach(MIMEText("这是一封包含附件的测试邮件。", "plain", "utf-8"))
# 附件(确保该路径下存在 test.pdf 文件)
with open("test.pdf", "rb") as f:
part = MIMEApplication(f.read(), Name="test.pdf")
part.add_header("Content-Disposition", "attachment", filename="test.pdf")
msg.attach(part)
server = smtplib.SMTP_SSL("smtp.qq.com", 465)
try:
server.login(sender, password)
server.sendmail(sender, [receiver], msg.as_string())
print("带附件邮件发送成功")
except smtplib.SMTPException as e:
print("发送失败:", e)
finally:
try:
server.quit()
except:
pass例 5:发送群发邮件
from email.mime.text import MIMEText
from email.header import Header
import smtplib
sender = "your@qq.com"
password = "your_auth_code"
receivers = ["user1@example.com", "user2@example.com", "user3@example.com"]
msg = MIMEText("大家好,这是一封群发测试邮件。", "plain", "utf-8")
msg["Subject"] = Header("群发测试", "utf-8")
msg["From"] = Header(sender)
msg["To"] = Header(", ".join(receivers)) # 显示在邮件头部
server = smtplib.SMTP_SSL("smtp.qq.com", 465)
try:
server.login(sender, password)
server.sendmail(sender, receivers, msg.as_string())
print("群发邮件发送成功")
except smtplib.SMTPException as e:
print("发送失败:", e)
finally:
try:
server.quit()
except:
pass◆ ◆ ◆
常用函数速览
ehlo(name='')
向 SMTP 服务器标识客户端身份,启用扩展 SMTP(ESMTP)功能。
参数:
name:可选,指定客户端的主机名,默认由系统自动获取
返回:
返回服务器响应的字符串信息。成功调用后,可使用服务器支持的扩展功能(如 STARTTLS)。
login(user, password)
登录 SMTP 服务器进行身份验证,适用于需要登录的邮箱服务。
参数:
user:邮箱用户名(一般为邮箱地址)
password:邮箱密码或专用授权码(如 Gmail 需启用 SMTP 并获取授权码)
返回:
返回服务器的登录响应信息。若失败,将抛出 SMTPAuthenticationError 异常。
quit()
发送 QUIT 命令,并优雅地关闭与服务器的连接。
参数:无
返回:
返回服务器关闭连接的响应信息。
sendmail(from_addr, to_addrs, msg)
向一个或多个收件人发送电子邮件。
参数:
from_addr:发件人地址(字符串)
to_addrs:收件人地址(字符串或字符串列表)
msg:完整的邮件内容(字符串,需包含邮件头和正文)
返回:成功发送时返回空字典。
若有收件人发送失败,则返回包含失败地址的字典。
set_debuglevel(level)
设置 SMTP 对话的调试输出等级,用于调试通信过程。
参数:
level:整数,1 表示开启调试输出,0 表示关闭
返回:无
starttls(keyfile=None, certfile=None, context=None)
将当前连接升级为加密的 TLS 连接,保障通信安全。
参数:
keyfile:可选,指定客户端私钥文件路径
certfile:可选,指定客户端证书文件路径
context:可选,ssl.SSLContext 对象,用于配置 TLS 加密参数
返回:无
若服务器不支持 STARTTLS 命令,将抛出 SMTPNotSupportedError。
◆ ◆ ◆
补充说明
1、邮件内容(尤其是附件或多格式邮件)应使用 email.mime 模块构造,不建议直接写字符串拼接。
2、如果邮箱使用了二步验证,请在设置中生成并使用“授权码”登录 SMTP,而非邮箱登录密码。
3、部分邮件服务商需手动开启“SMTP 服务”,否则连接将被拒绝。
4、sendmail() 中的收件人必须是列表类型,即使只有一个邮箱地址也应写成 [addr]。
5、推荐设置 set_debuglevel(1) 进行测试,可以看到完整通信过程。
“点赞有美意,赞赏是鼓励”
热门跟贴