python使用smtp发送邮件
一、概述
与发送邮件相关的 Python 模块:
smtplib
是关于 SMTP(简单邮件传输协议)的操作模块,在发送邮件的过程中起到服务器之间互相通信的作用。
email
简单来说,即服务器之间通信的信息,包括信息头、信息主体等等。
举个简单的例子,当你登录邮箱,写好邮件后点击发送,这部分是由 SMTP 接管;而写邮件、添加附件是由 email 模块控制。
二、开通电子邮箱的SMTP功能
在使用脚本发邮件之前,我们需要打开自己邮箱的 SMTP 功能,各家邮箱的设置方法就不一一讲述了,具体使用时可以百度一下,下面以 163 邮箱设置为例做一个简单的演示:
三、代码操作
class MailServer:
def __init__(self, address, port):
self.address = address
self.port = port
class MailUser:
def __init__(self, user, password):
self.user = user
self.password = password
class SMTPSender:
"""邮件通知"""
_instance = None
@classmethod
def get_instance(cls):
"""单例模式"""
if SMTPSender._instance is None:
SMTPSender._instance = SMTPSender()
return SMTPSender._instance
def __init__(self):
self.message = None
self.client = None
self.use_ssl = False
self.server = None
self.user = None
def set_ssl(self, is_ssl):
self.use_ssl = is_ssl
def set_server(self, address, port):
self.server = MailServer(address, port)
def set_user(self, user, password):
self.user = MailUser(user, password)
def __del__(self):
try:
if self.client:
self.client.quit()
self.client = None
except:
pass
def _connect(self):
"""连接服务器"""
if self.use_ssl:
self.client = smtplib.SMTP_SSL(self.server.address, self.server.port)
else:
self.client = smtplib.SMTP(self.server.address, self.server.port)
try:
# outlook 需要starttls 否则无法发送邮件 其他的不需要
self.client.starttls()
except:
pass
def login(self):
"""登录邮箱"""
self.client.login(self.user.user, self.user.password)
log.info("邮箱登录成功")
def logout(self):
if self.client:
self.client.close()
self.client = None
def set_smtp_header(self, sender, receivers, subject, cc=[], bcc=[]):
"""设置协议头"""
self.message['From'] = sender
self.message['To'] = Header(','.join(receivers))
self.message['Subject'] = Header(subject)
self.message['Cc'] = Header(','.join(cc))
self.message['Bcc'] = Header(','.join(bcc))
def set_smtp_content(self, content, content_type, encoding):
"""设置正文内容"""
alternative = MIMEMultipart('alternative')
text_html = MIMEText(content, _subtype=content_type, _charset=encoding)
alternative.attach(text_html)
self.message.attach(alternative)
def set_smtp_attachment(self, filepath, display_name=None):
"""设置单个附件"""
attachment = MIMEApplication(open(filepath, 'rb').read())
attachment.add_header("Content-Type", 'application/octet-stream')
if display_name is None:
display_name = os.path.basename(filepath)
attachment.add_header('Content-Disposition', 'attachment', filename=Header(display_name).encode())
self.message.attach(attachment)
def set_smtp_attachments(self, filepaths, display_names=None):
"""设置附件"""
for i in range(len(filepaths)):
filepath = filepaths[i]
display_name = display_names[i] if display_names else None
self.set_smtp_attachment(filepath, display_name)
def create_smtp_message(self,
receivers,
cc=[],
bcc=[],
subject="",
content=None,
content_type='utf-8',
file_paths=[],
display_names=[]):
"""构造邮箱报文"""
self.message = MIMEMultipart('mixed')
self.set_smtp_header(self.user.user, receivers, subject, cc, bcc)
if content:
self.set_smtp_content(content, 'html', content_type)
if file_paths:
self.set_smtp_attachments(file_paths, display_names)
def send_mail(self, subject, content='', cc=[], bcc=[], receivers=[], filenames=[]):
"""发送 邮件 subject、recipient、content 属于必填项
content:{
'subject': '*标题',
'recipient': ['*收件人邮箱1', '收件人邮箱2'],
'cc': ['抄送邮箱1', ’抄送邮箱2‘],
'bcc': ['密送邮箱1', '密送邮箱2'],
'content': '*正文 支持html',
'filenames': ['文件路径列表']
}
"""
assert self.server, '请设置邮箱服务器信息'
assert self.user, '请设置user登录信息'
if not self.client:
self._connect()
self.login()
self.create_smtp_message(receivers=receivers,
cc=cc,
bcc=bcc,
subject=subject,
content=content,
file_paths=filenames)
self.client.sendmail(self.user.user, receivers + cc + bcc, self.message.as_string())
根据对应信息设置
instance = SMTPSender.get_instance()
instance.set_server(email_info.get("邮箱服务器地址"), int(email_info.get("邮箱服务器端口")))
instance.set_user(email_info.get("邮箱账号"), email_info.get("邮箱密码"))
instance.set_ssl(True)
SMTPSender.get_instance().logout()
标签:set,python,self,smtp,content,def,user,邮箱,邮件
From: https://blog.csdn.net/weixin_45014634/article/details/142917802