033-Python SMTP发送邮件
Python 提供了内置的 smtplib
模块,用于通过 SMTP(Simple Mail Transfer Protocol) 协议发送电子邮件。SMTP 是一种简单的邮件传输协议,广泛用于电子邮件服务。
以下是 Python 使用 SMTP 发送邮件的完整指南。
1. 基本使用:发送简单文本邮件
1.1 示例:发送文本邮件
以下是使用 smtplib
发送邮件的最简单示例。
import smtplib
from email.mime.text import MIMEText
# 邮件发送方和接收方
sender = "youremail@example.com"
receiver = "receiver@example.com"
# 邮件内容
subject = "Python SMTP 邮件测试"
body = "这是一封通过 Python 发送的测试邮件。"
# 创建 MIMEText 对象
message = MIMEText(body, "plain", "utf-8")
message["From"] = sender
message["To"] = receiver
message["Subject"] = subject
# 发送邮件
try:
# 连接到 SMTP 服务器
smtp = smtplib.SMTP("smtp.example.com", 587) # 使用 587 端口(适用于 TLS)
smtp.starttls() # 启用 TLS 加密
smtp.login("youremail@example.com", "yourpassword") # 登录 SMTP 服务器
smtp.sendmail(sender, receiver, message.as_string()) # 发送邮件
print("邮件发送成功!")
except Exception as e:
print("邮件发送失败:", e)
finally:
smtp.quit() # 断开连接
1.2 关键点解释
smtplib.SMTP
:- 用于连接 SMTP 服务器。
- 常见的端口:
587
:适用于 TLS(推荐)。465
:适用于 SSL。25
:不加密(不推荐)。starttls()
:- 启用 TLS 加密。
MIMEText
:- 用于构建电子邮件正文。
- 参数说明:
- 第一个参数:邮件内容。
- 第二个参数:内容类型(
plain
表示纯文本,html
表示 HTML 格式)。 - 第三个参数:编码格式(通常为
utf-8
)。
2. 发送带附件的邮件
如果需要发送带附件的邮件,可以使用 email.mime.multipart
模块。
2.1 示例:发送带附件的邮件
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email import encoders
# 邮件发送方和接收方
sender = "youremail@example.com"
receiver = "receiver@example.com"
# 创建邮件对象
message = MIMEMultipart()
message["From"] = sender
message["To"] = receiver
message["Subject"] = "Python SMTP 邮件测试(带附件)"
# 添加邮件正文
body = "这是一封带附件的测试邮件。"
message.attach(MIMEText(body, "plain", "utf-8"))
# 添加附件
file_path = "example.txt" # 附件文件路径
with open(file_path, "rb") as attachment:
mime_base = MIMEBase("application", "octet-stream")
mime_base.set_payload(attachment.read())
encoders.encode_base64(mime_base) # 对附件内容进行 Base64 编码
mime_base.add_header(
"Content-Disposition", f"attachment; filename={file_path}"
)
message.attach(mime_base)
# 发送邮件
try:
smtp = smtplib.SMTP("smtp.example.com", 587)
smtp.starttls()
smtp.login("youremail@example.com", "yourpassword")
smtp.sendmail(sender, receiver, message.as_string())
print("邮件发送成功!")
except Exception as e:
print("邮件发送失败:", e)
finally:
smtp.quit()
3. 发送 HTML 格式的邮件
为了让邮件更美观,可以使用 HTML 格式的内容。
3.1 示例:发送 HTML 邮件
import smtplib
from email.mime.text import MIMEText
# 邮件发送方和接收方
sender = "youremail@example.com"
receiver = "receiver@example.com"
# HTML 内容
html_content = """
<!DOCTYPE html>
<html>
<body>
<h1 style="color:blue;">Python SMTP HTML 邮件测试</h1>
<p>这是一封通过 Python 发送的 HTML 格式的邮件。</p>
</body>
</html>
"""
# 创建 HTML 邮件
message = MIMEText(html_content, "html", "utf-8")
message["From"] = sender
message["To"] = receiver
message["Subject"] = "Python HTML 邮件测试"
# 发送邮件
try:
smtp = smtplib.SMTP("smtp.example.com", 587)
smtp.starttls()
smtp.login("youremail@example.com", "yourpassword")
smtp.sendmail(sender, receiver, message.as_string())
print("HTML 邮件发送成功!")
except Exception as e:
print("邮件发送失败:", e)
finally:
smtp.quit()
4. 批量发送邮件
批量发送邮件时,可以将多个接收者地址放入 To
字段中,或使用循环发送。
4.1 示例:批量发送邮件
import smtplib
from email.mime.text import MIMEText
# 邮件发送方
sender = "youremail@example.com"
receivers = ["receiver1@example.com", "receiver2@example.com", "receiver3@example.com"]
# 邮件内容
subject = "Python 批量邮件测试"
body = "这是一封通过 Python 发送的批量测试邮件。"
# 创建 MIMEText 对象
message = MIMEText(body, "plain", "utf-8")
message["From"] = sender
message["Subject"] = subject
# 发送邮件
try:
smtp = smtplib.SMTP("smtp.example.com", 587)
smtp.starttls()
smtp.login("youremail@example.com", "yourpassword")
for receiver in receivers:
message["To"] = receiver
smtp.sendmail(sender, receiver, message.as_string())
print(f"邮件已发送给:{receiver}")
except Exception as e:
print("邮件发送失败:", e)
finally:
smtp.quit()
5. 使用第三方邮件服务
5.1 使用 Gmail SMTP
Gmail 提供免费的 SMTP 服务,可以通过以下方式发送邮件。
注意:
- 确保在 Gmail 设置中启用了 “允许不太安全的应用”(或生成应用专用密码)。
- Gmail SMTP 服务器地址:
smtp.gmail.com
。
import smtplib
from email.mime.text import MIMEText
# 邮件发送方和接收方
sender = "yourgmail@gmail.com"
receiver = "receiver@example.com"
# 邮件内容
subject = "Gmail SMTP 测试"
body = "这是一封通过 Gmail SMTP 发送的测试邮件。"
# 创建 MIMEText 对象
message = MIMEText(body, "plain", "utf-8")
message["From"] = sender
message["To"] = receiver
message["Subject"] = subject
# 发送邮件
try:
smtp = smtplib.SMTP("smtp.gmail.com", 587)
smtp.starttls()
smtp.login("yourgmail@gmail.com", "yourpassword") # 或使用应用专用密码
smtp.sendmail(sender, receiver, message.as_string())
print("Gmail 邮件发送成功!")
except Exception as e:
print("邮件发送失败:", e)
finally:
smtp.quit()
5.2 使用 QQ 邮箱 SMTP
QQ 邮箱也支持 SMTP 服务,但需在设置中开启 SMTP 服务 并获取授权码。
smtp.qq.com
。465
(SSL)或 587
(TLS)。import smtplib
from email.mime.text import MIMEText
# 邮件发送方和接收方
sender = "yourqq@qq.com"
receiver = "receiver@example.com"
# 邮件内容
subject = "QQ 邮箱 SMTP 测试"
body = "这是一封通过 QQ 邮箱 SMTP 发送的测试邮件。"
# 创建 MIMEText 对象
message = MIMEText(body, "plain", "utf-8")
message["From"] = sender
message["To"] = receiver
message["Subject"] = subject
# 发送邮件
try:
smtp = smtplib.SMTP_SSL("smtp.qq.com", 465) # 使用 SSL 加密
smtp.login("yourqq@qq.com", "yourauthorizationcode") # QQ 邮箱授权码
smtp.sendmail(sender, receiver, message.as_string())
print("QQ 邮件发送成功!")
except Exception as e:
print("邮件发送失败:", e)
finally:
smtp.quit()
6. 常见问题及解决方法
6.1 常见错误
-
smtplib.SMTPAuthenticationError
: - 表示邮箱用户名或密码(授权码)错误。
- 解决方法:检查邮箱账号、密码或授权码是否正确。
-
smtplib.SMTPConnectError
: - 表示无法连接到 SMTP 服务器。
- 解决方法:检查服务器地址和端口是否正确,网络是否通畅。
-
smtplib.SMTPDataError
: - 表示邮件内容不符合 SMTP 协议。
- 解决方法:检查邮件格式,确保邮件头和正文正确。
-
Gmail 或 QQ 邮箱登录失败:
- 检查是否启用了 SMTP 服务。
- 使用应用专用密码或授权码,而不是直接使用邮箱密码。
7. 总结
通过 Python 的 smtplib
模块,您可以轻松实现以下功能:
- 发送普通文本邮件。
- 发送带附件的邮件。
- 发送 HTML 格式的邮件。
- 批量发送邮件。
此外,还可以结合第三方邮件服务(如 Gmail、QQ 邮箱)实现更高效的邮件发送。对于企业级应用,建议使用邮件 API(如 SendGrid 或 AWS SES)以提升邮件发送的可靠性和扩展性。
以下将继续扩展 Python SMTP发送邮件 的内容,涵盖更高级应用、邮件模板、邮件队列、自动化发送、第三方邮件服务集成以及常见问题的深入解决方案。
8. 高级邮件发送功能
8.1 发送带图片的邮件
在邮件正文中嵌入图片,可以增强邮件的视觉效果。通过 MIMEImage
模块实现。
发送嵌入图片的邮件
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.image import MIMEImage
# 邮件发送方和接收方
sender = "youremail@example.com"
receiver = "receiver@example.com"
# 创建邮件对象
message = MIMEMultipart("related")
message["From"] = sender
message["To"] = receiver
message["Subject"] = "带嵌入图片的邮件测试"
# 邮件正文(HTML 格式)
html_content = """
<!DOCTYPE html>
<html>
<body>
<h1>Python 邮件测试</h1>
<p>这是一个带嵌入图片的邮件测试。</p>
<img src="cid:image1">
</body>
</html>
"""
message.attach(MIMEText(html_content, "html", "utf-8"))
# 添加图片
with open("example.jpg", "rb") as img:
mime_image = MIMEImage(img.read())
mime_image.add_header("Content-ID", "<image1>") # 用于 HTML 中引用
message.attach(mime_image)
# 发送邮件
try:
smtp = smtplib.SMTP("smtp.example.com", 587)
smtp.starttls()
smtp.login("youremail@example.com", "yourpassword")
smtp.sendmail(sender, receiver, message.as_string())
print("邮件发送成功!")
except Exception as e:
print("邮件发送失败:", e)
finally:
smtp.quit()
8.2 使用 HTML 模板生成邮件内容
在实际应用中,邮件内容通常来源于模板。可以使用 Jinja2
模板引擎动态生成 HTML 内容。
安装 Jinja2
pip install Jinja2
示例:渲染 HTML 邮件模板
- 创建 HTML 模板(
email_template.html
)
<!DOCTYPE html>
<html>
<body>
<h1>欢迎,{
{ name }}!</h1>
<p>这是您的定制化邮件内容。</p>
<p>日期:{
{ date }}</p>
</body>
</html>
html 4
在画布上打开
- 使用 Jinja2 渲染模板
from jinja2 import Environment, FileSystemLoader
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from datetime import datetime
# 加载模板
env = Environment(loader=FileSystemLoader("."))
template = env.get_template("email_template.html")
# 渲染模板
html_content = template.render(name="Alice", date=datetime.now().strftime("%Y-%m-%d"))
# 邮件发送方和接收方
sender = "youremail@example.com"
receiver = "receiver@example.com"
# 创建邮件对象
message = MIMEMultipart()
message["From"] = sender
message["To"] = receiver
message["Subject"] = "使用 HTML 模板的邮件"
# 添加渲染后的 HTML 内容
message.attach(MIMEText(html_content, "html", "utf-8"))
# 发送邮件
try:
smtp = smtplib.SMTP("smtp.example.com", 587)
smtp.starttls()
smtp.login("youremail@example.com", "yourpassword")
smtp.sendmail(sender, receiver, message.as_string())
print("邮件发送成功!")
except Exception as e:
print("邮件发送失败:", e)
finally:
smtp.quit()
8.3 定时发送邮件
可以使用 schedule
或 APScheduler
库实现邮件的定时发送。
安装 schedule
pip install schedule
示例:定时发送邮件
import smtplib
from email.mime.text import MIMEText
import schedule
import time
# 邮件发送函数
def send_email():
sender = "youremail@example.com"
receiver = "receiver@example.com"
subject = "定时邮件"
body = "这是一个定时发送的测试邮件。"
message = MIMEText(body, "plain", "utf-8")
message["From"] = sender
message["To"] = receiver
message["Subject"] = subject
try:
smtp = smtplib.SMTP("smtp.example.com", 587)
smtp.starttls()
smtp.login("youremail@example.com", "yourpassword")
smtp.sendmail(sender, receiver, message.as_string())
print("邮件发送成功!")
except Exception as e:
print("邮件发送失败:", e)
finally:
smtp.quit()
# 定时任务:每天早上 9 点发送邮件
schedule.every().day.at("09:00").do(send_email)
print("定时任务已启动...")
while True:
schedule.run_pending()
time.sleep(1)
9. 集成第三方邮件服务
除了直接使用 SMTP,还可以通过第三方邮件服务(如 SendGrid、AWS SES、Mailgun 等)发送邮件,这些服务通常提供更高的可靠性和扩展性。
9.1 使用 SendGrid
安装 SendGrid SDK
pip install sendgrid
示例:使用 SendGrid 发送邮件
from sendgrid import SendGridAPIClient
from sendgrid.helpers.mail import Mail
# 创建邮件对象
message = Mail(
from_email="youremail@example.com",
to_emails="receiver@example.com",
subject="SendGrid 邮件测试",
html_content="<strong>这是一封通过 SendGrid 发送的测试邮件。</strong>"
)
# 发送邮件
try:
sg = SendGridAPIClient("your_sendgrid_api_key") # 替换为你的 SendGrid API 密钥
response = sg.send(message)
print(f"邮件发送成功,状态码:{response.status_code}")
except Exception as e:
print(f"邮件发送失败:{e}")
9.2 使用 AWS SES
安装 Boto3
pip install boto3
示例:使用 AWS SES 发送邮件
import boto3
# 创建 SES 客户端
ses = boto3.client(
"ses",
aws_access_key_id="your_aws_access_key",
aws_secret_access_key="your_aws_secret_key",
region_name="us-east-1" # 替换为你的 AWS 区域
)
# 发送邮件
response = ses.send_email(
Source="youremail@example.com",
Destination={
"ToAddresses": ["receiver@example.com"]
},
Message={
"Subject": {
"Data": "AWS SES 邮件测试"
},
"Body": {
"Html": {
"Data": "<h1>这是一封通过 AWS SES 发送的测试邮件。</h1>"
}
}
}
)
print(f"邮件发送成功!Message ID:{response['MessageId']}")
10. 邮件自动化与队列
在大规模邮件发送场景中(如营销邮件),可以结合消息队列(如 RabbitMQ、Redis 等)实现邮件自动化发送。
示例:结合 Celery 和 Redis 实现邮件队列
- 安装依赖
pip install celery[redis] smtplib
- 创建 Celery 配置
from celery import Celery
import smtplib
from email.mime.text import MIMEText
app = Celery("tasks", broker="redis://localhost:6379/0")
@app.task
def send_email_task(to_email, subject, body):
sender = "youremail@example.com"
message = MIMEText(body, "plain", "utf-8")
message["From"] = sender
message["To"] = to_email
message["Subject"] = subject
try:
smtp = smtplib.SMTP("smtp.example.com", 587)
smtp.starttls()
smtp.login("youremail@example.com", "yourpassword")
smtp.sendmail(sender, to_email, message.as_string())
smtp.quit()
print(f"邮件已发送给:{to_email}")
except Exception as e:
print(f"邮件发送失败:{e}")
- 调用任务
from tasks import send_email_task
# 调用任务
send_email_task.delay("receiver@example.com", "Celery 邮件测试", "这是一封通过 Celery 发送的测试邮件。")
11. 总结
通过扩展,您现在掌握了以下高级邮件发送功能:
- 邮件内容增强:嵌入图片、使用 HTML 模板。
- 定时和批量发送:使用
schedule
或任务队列(如 Celery)。 - 集成第三方服务:如 SendGrid 和 AWS SES,提升邮件可靠性。
- 邮件队列:使用 Celery 实现高效的邮件队列管理。
无论是个人项目还是企业应用,这些技能都可以帮助您构建高效、灵活的邮件发送系统!
作者:小宝哥Code