Python快乐学习、快乐成长
1、邮件发送
Python3 中应用的SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式。
2、发送纯文本邮件
smtplib提供了一种很方便的途径发送电子邮件。它对 smtp 协议进行了简单的封装。
Python创建 SMTP 对象语法如下:
import smtplib
smtpObj = smtplib.SMTP( [host [, port [, local_hostname]]] )
示列代码:
python
import smtplib
from email.mime.text import MIMEText
# 1. 配置邮件发送信息(替换成自己的信息)
sender = "你的邮箱地址@qq.com" # 发件人邮箱
password = "你的邮箱授权码" # 不是登录密码,是授权码
receiver = "接收人邮箱地址@163.com" # 收件人邮箱(可多个,用列表:["a@163.com", "b@qq.com"])
smtp_server = "smtp.qq.com" # 对应邮箱的SMTP服务器地址
smtp_port = 465 # SSL加密端口,固定465
# 2. 构建邮件内容(纯文本)
mail_subject = "Python SMTP 测试邮件" # 邮件主题
mail_content = "这是用 Python3 smtplib 发送的纯文本测试邮件,新手入门必看!" # 邮件正文
# 创建邮件对象,指定编码(防止中文乱码)
msg = MIMEText(mail_content, "plain", "utf-8")
msg["From"] = sender # 发件人
msg["To"] = receiver # 收件人(多个收件人用逗号分隔)
msg["Subject"] = mail_subject # 邮件主题
# 3. 连接SMTP服务器并发送邮件
try:
# 连接SMTP服务器(SSL加密方式)
server = smtplib.SMTP_SSL(smtp_server, smtp_port)
# 登录邮箱
server.login(sender, password)
# 发送邮件(sender:发件人,receiver:收件人,msg.as_string():邮件内容转字符串)
server.sendmail(sender, receiver, msg.as_string())
print("邮件发送成功!")
except Exception as e:
print(f"邮件发送失败,错误信息:{e}")
finally:
# 关闭连接
server.quit()
解析:
- smtplib.SMTP_SSL():使用 SSL 加密连接 SMTP 服务器,避免邮件内容被窃取,端口固定为 465(推荐使用,更安全);
- MIMEText():创建纯文本邮件对象,参数分别是「邮件正文」「邮件格式(plain 为纯文本)」「编码(utf-8 防止中文乱码)」;
- msg["From"]/["To"]/["Subject"]:设置邮件的发件人、收件人、主题,必须填写,否则邮件会被判定为垃圾邮件;
- server.login():用发件人邮箱和授权码登录 SMTP 服务器;
- server.sendmail():发送邮件,第三个参数必须是邮件对象转字符串(msg.as_string());
- try-except-finally:捕获发送过程中的异常,确保无论成功与否,都关闭服务器连接。
3、发送带附件的邮件
实际应用中,我们经常需要发送带附件的邮件(如报表、文档、图片等),这时候需要用到 email.mime.multipart.MIMEMultipart 模块,实现「正文+附件」的组合发送。
示例代码如下:
python
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.header import Header # 用于设置邮件主题中文格式
# 1. 配置邮件发送信息(替换成自己的信息)
sender = "你的邮箱地址@163.com"
password = "你的邮箱授权码"
receiver = ["接收人1@qq.com", "接收人2@163.com"] # 多个收件人,用列表
smtp_server = "smtp.163.com"
smtp_port = 465
# 2. 构建邮件对象(支持附件)
msg = MIMEMultipart()
msg["From"] = sender
msg["To"] = ",".join(receiver) # 多个收件人用逗号分隔,转字符串
msg["Subject"] = Header("Python SMTP 带附件测试邮件", "utf-8") # 中文主题,避免乱码
# 3. 邮件正文(可写HTML格式,也可写纯文本)
mail_content = """
这是用 Python 发送的带附件测试邮件附件包含:测试文档和测试图片新手可直接复制代码,替换自己的信息即可使用!
"""
# 正文内容(HTML格式,更美观)
text_part = MIMEText(mail_content, "html", "utf-8")
msg.attach(text_part) # 将正文添加到邮件对象中
# 4. 添加附件(支持多个附件,重复以下代码即可)
# 附件1:测试文档(txt格式)
attachment1 = MIMEText(open("test.txt", "rb").read(), "base64", "utf-8")
attachment1["Content-Type"] = "application/octet-stream" # 附件类型
# 设置附件显示名称(中文需用Header处理,避免乱码)
attachment1["Content-Disposition"] = 'attachment; filename="测试文档.txt"'
msg.attach(attachment1) # 将附件添加到邮件对象
# 附件2:测试图片(jpg格式)
attachment2 = MIMEText(open("test.jpg", "rb").read(), "base64", "utf-8")
attachment2["Content-Type"] = "application/octet-stream"
attachment2["Content-Disposition"] = 'attachment; filename="测试图片.jpg"'
msg.attach(attachment2)
# 5. 发送邮件
try:
server = smtplib.SMTP_SSL(smtp_server, smtp_port)
server.login(sender, password)
server.sendmail(sender, receiver, msg.as_string())
print("带附件邮件发送成功!")
except Exception as e:
print(f"带附件邮件发送失败,错误信息:{e}")
finally:
server.quit()
解析:
- MIMEMultipart():创建支持多部分内容(正文+附件)的邮件对象,是发送附件的核心;
- Header():处理中文主题,避免中文乱码(纯文本主题可不用,但推荐使用);
- 邮件正文支持 HTML 格式:将 MIMEText 的第二个参数改为 "html",即可在正文中使用 HTML 标签让正文更美观;
- 添加附件:
- 用 open() 以二进制模式(rb)读取附件文件;
- 用 MIMEText 对附件内容进行 base64 编码(避免附件损坏);
- 设置 Content-Type 为 application/octet-stream(通用附件类型);
- 设置 Content-Disposition,指定附件显示名称(filename 可自定义);
- 用 msg.attach() 将附件添加到邮件对象中,多个附件重复此步骤即可。
4、定时发送邮件
安装依赖库,语法如下:
pip install schedule # 用于定时任务
定时发送代码示例:
python
import smtplib
import schedule
import time
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
# 1. 定义邮件发送函数(复用之前的带附件逻辑)
def send_email():
sender = "你的邮箱地址@qq.com"
password = "你的邮箱授权码"
receiver = "接收人邮箱@163.com"
smtp_server = "smtp.qq.com"
smtp_port = 465
msg = MIMEMultipart()
msg["From"] = sender
msg["To"] = receiver
msg["Subject"] = "每日定时测试邮件"
# 正文
content = f"当前时间:{time.strftime('%Y-%m-%d %H:%M:%S')}\n这是每日定时发送的邮件,自动化测试成功!"
text_part = MIMEText(content, "plain", "utf-8")
msg.attach(text_part)
# 发送邮件
try:
server = smtplib.SMTP_SSL(smtp_server, smtp_port)
server.login(sender, password)
server.sendmail(sender, receiver, msg.as_string())
print(f"{time.strftime('%Y-%m-%d %H:%M:%S')} 定时邮件发送成功!")
except Exception as e:
print(f"定时邮件发送失败,错误信息:{e}")
finally:
server.quit()
# 2. 设置定时任务(每天8:00发送)
schedule.every().day.at("08:00").do(send_email)
# 3. 循环执行定时任务
print("定时任务已启动,等待发送邮件...")
while True:
schedule.run_pending() # 检查是否有定时任务需要执行
time.sleep(60) # 每隔60秒检查一次
解析:
- schedule.every().day.at("08:00").do(send_email):设置每天8:00执行 send_email 函数;
- while True + schedule.run_pending():循环检查定时任务,确保任务能按时执行;
- time.sleep(60):每隔60秒检查一次,避免占用过多CPU资源;
- 如果需要修改定时规则,可参考:
- 每小时发送:schedule.every().hour.do(send_email)
- 每周一8:00发送:schedule.every().monday.at("08:00").do(send_email)
- 每隔30分钟发送:schedule.every(30).minutes.do(send_email)
5、常见问题排查
1. 错误:smtplib.SMTPAuthenticationError: (535, b'Login fail. Please enter your authorization code to login.')
原因:授权码错误,或未开启 SMTP 服务。
解决方案:重新检查授权码,确认邮箱的 SMTP 服务已开启,重新生成授权码重试。
2. 错误:smtplib.SMTPConnectError: Connection refused
原因:SMTP 服务器地址或端口错误。
解决方案:核对邮箱的 SMTP 服务器地址和端口,确保使用 465 端口(SSL 加密)。
3. 邮件发送成功,但收件人收不到
原因:邮件被判定为垃圾邮件,或收件人地址错误。
解决方案:检查收件人地址;在收件人邮箱的垃圾邮件箱中查找,标记为正常邮件;优化邮件主题和正文,避免使用敏感词汇(如"广告""推广""测试"可适当修改)。
4. 中文乱码
原因:未设置正确的编码,或中文主题/附件名未用Header 处理。
解决方案:确保 MIMEText 的编码为 utf-8,中文主题用 Header() 处理,中文附件名也用 Header() 处理。
5. 附件无法打开或损坏
原因:读取附件时未用二进制模式(rb),或编码错误。
解决方案:确保读取附件时使用 open("文件路径", "rb"),附件编码设置为 base64。
结尾
记录自己的快乐学习日志,也祝贺观看到这的小伙伴早日学有所成,财富自由💰💰。
记得点赞👍、收藏👋呀!!!