文章目录
- 一、SMTP协议邮件准备
- 二、smtplib模块
- 1.使用smtplib封装一个邮件类
- 2.发送邮件
- 补充
一、SMTP协议邮件准备
需要一个smtp服务器
二、smtplib模块
smtplib模块是python自带的模块
1.使用smtplib封装一个邮件类
import smtplib
import logging # 加入日志,保持这个好习惯,使用前需要配置
class Smtp(object): # 类名自定义
def __init__(self, sender, pwd, server_url, server_port):
"""
sender 登录SMTP服务器的用户名 注意除了使用用户名和密码还可使用密钥
pwd 登录SMTP服务器的密码
server_url SMTP服务器域名或者IP
server_port SMTP服务所开放的端口
"""
self.sender = sender
self.smtp = smtplib.SMTP(server_url, server_port, timeout=5) # 创建smtp对象
self.smtp.starttls() # 开始TSL加密
self.smtp.login(sender, pwd) # 使用密码或者密码获取登陆凭证
def mail(self, *args): # 发送邮件
"""
俩个参数依次为:收信邮箱、内容
"""
self.smtp.sendmail(self.sender, args[0], args[1])
def stop_mail(self): # 邮件发送完毕后需要关闭连接,释放资源
"""
停止smtp
"""
self.smtp.quit()
2.发送邮件
代码如下(示例):
import multiprocessing # 进程模块
import smtplib
from email.header import Header
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
def send_mail(send_user, send_pwd, server_url, server_port, to_mail, msg): # msg为smtp的html内容对象,需要完成复杂邮件内容时需要用到MIMEMultipart,此处的msg便为MIMEMultipart(复杂内容为,附件、表格、图片等)
smtp_send = Smtp(send_user, send_pwd, server_url, server_port) # 户名、密码、域名、端口
smtp_send.mail(to_mail, msg.as_string()) # 收信人邮箱、bytes数据(直接放字符串内容也行,smtplib会自动转化)
smtp_send.stop_mail() # 发信完毕,停止连接
补充
完成上诉代码就能发送邮件了,但STMP协议发送邮件时会阻塞主进程以及网络,所以当你要异步发送smtp协议的邮件时使用线程、协程时无法达成异步效果的,需要开启新的进程
附上完整代码以及进程发送邮件
我代码中邮箱的表格样式:
import logging
import multiprocessing
import smtplib
from email.header import Header
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
error_logger = logging.getLogger('celery-error')
class Smtp(object): # 类名自定义
def __init__(self, sender, pwd, server_url, server_port):
"""
sender登录SMTP服务器的用户名 一般为发信邮箱 注意除了使用用户名和密码还可使用密钥
pwd 登录SMTP服务器的密码
server_url SMTP服务器域名或者IP
server_port SMTP服务所开放的端口
"""
self.sender = sender
self.smtp = smtplib.SMTP(server_url, server_port, timeout=5) # 创建smtp对象
self.smtp.starttls() # 开始TSL加密
self.smtp.login(sender, pwd) # 使用密码或者密码获取登陆凭证
def mail(self, *args): # 发送邮件
"""
俩个参数依次为:收信邮箱、内容
"""
self.smtp.sendmail(self.sender, args[0], args[1])
def stop_mail(self): # 邮件发送完毕后需要关闭连接,释放资源
"""
停止smtp
"""
self.smtp.quit()
def send_mail(send_user, send_pwd, server_url, server_port, to_mail, msg): # msg为smtp的html内容对象,需要完成复杂邮件内容时需要用到MIMEMultipart,此处的msg便为MIMEMultipart(复杂内容为,附件、表格、图片等)
smtp_send = Smtp(send_user, send_pwd, server_url, server_port) # 户名、密码、域名、端口
smtp_send.mail(to_mail, msg.as_string()) # 收信人邮箱、bytes数据(直接放字符串内容也行,smtplib会自动转化)
smtp_send.stop_mail() # 发信完毕,停止连接
def mail_to_user(**kwargs):
user_obj = Users.objects.filter(username=kwargs.get('touser')).first()
try:
if user_obj:
# 收信人邮箱
send_user = 'kkk@qq.com'
# 创建MIMEMultipart对象,此处我生成了一个table表格
msg = MIMEMultipart()
# 设置邮件主题和发件人信息
msg['From'] = key_obj.accessSecret
msg['To'] = send_user
msg['Subject'] = Header("测试邮件", 'utf-8')
# 创建表格内容的列表
table_data = ["测试类型", "测试状态", "申请人", "2023-9-26"]
# 初始化表格HTML字符串
table_html = """
<table>
<tr>
<th>类型</th>
<th>状态</th>
<th>申请人</th>
<th>预约完成日期</th>
</tr>
"""
# 构建表格内容的HTML字符串 如果此处内容时多行的可以循坏拼接这一段
table_html += f"""
<tr>
<td>{table_data[0]}</td>
<td>{table_data[1]}</td>
<td>{table_data[2]}</td>
<td>{table_data[3]}</td>
</tr>
"""
table_html += "</table>"
# 将表格内容html加入到html代码中
html_content = """
<html>
<style type="text/css">
table thead, table tr {
border-top-width: 1px;
border-top-style: solid;
border-top-color: rgb(211, 202, 221);
}
table {
border-bottom-width: 1px;
border-bottom-style: solid;
border-bottom-color: rgb(211, 202, 221);
}
table td, table th {
padding: 5px 10px;
font-size: 12px;
font-family: Verdana;
color: rgb(95, 74, 121);
}
table tr:nth-child(even) {
background: rgb(223, 216, 232)
}
table tr:nth-child(odd) {
background: #FFF
}
</style>
<body>
""" + table_html + """
</body>
</html>
"""
# 将表格内容作为MIMEText对象添加到邮件中
table_part = MIMEText(html_content, 'html', 'utf-8')
msg.attach(table_part)
process = multiprocessing.Process(target=send_mail, args=("admin@qq.com", "password", "127.0.0.1", 8043, "test@qq.com", msg))
process.start()
except Exception as e:
print(str(e))
error_logger.error('邮件发送错误 ' + str(e))