邮件其实是支持HTML写法的,我想刚开始学这个的大部分都不知道吧;大家QQ可能经常收到一些垃圾邮件或广告邮件,如果能看到邮件内容原格式,就会发现其实都是HTML的代码。这对于工作中遇到的反复、频繁发邮件的工作来说,手工发送效率太差又耗费精力,这时候就需要一些写好的python email类简单实用方便调用就可以了。
附上python3的完整版代码如下(只需要用的看末尾代码):
#coding:utf-8
import os
import smtplib
from email.mime.text import MIMEText
from email import encoders
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication
from email.mime.image import MIMEImage
from email.header import Header
class emailObj:
'''
模块化邮件类
'''
def __init__(self,_user="", _vaild="", _host=None, _port=443):
self.host = "email.host.com" if _host is None else _host
self.port = _port
self.mailUser = _user
self.mailPass = _vaild
def sendMail(self, _cont, _recv, _ands, _subJect, _blindRecv="", _imgList=None, _attf=None):
'''
发送一封邮箱,其需要的参数已经在类实例化中初始化
:param _cont: 邮件的内容,可以将html整个内容传入,注意文件不要太大,可能会溢出
:param _recv: 收件人,多个收件人以;分隔
:param _ands: 抄送
:param _subJect: 邮件的主题
:param _blindRecv: 【邮件密送】
:param _imgList: 图片列表
:param _attf: 附件列表
:return: 返回成功或失败的信息
'''
reCode,errMsg = False,None
self.smtpObj = smtplib.SMTP()
try:
self.smtpObj.connect(self.host, self.port)
#ehlo是对helo的扩展,即extend helo,可以支持用户认证(authorization),ehlo方法表示自己需要身份验证
self.smtpObj.ehlo()
#有些邮箱服务器不用ehlo也行,login与ehlo不冲突。
Res = self.smtpObj.login(self.mailUser, self.mailPass) # 返回码:235连接正常
receiveList = _recv.split(';') if type(_recv) is str else _recv
andSendList = _ands.split(';') if type(_ands) is str else _recv
blindSendList = _blindRecv.split(',') if type(_blindRecv)==str else _recv
msg = MIMEMultipart('related')
message = MIMEText(_cont, 'html', 'utf-8')
msg['From'] = self.mailUser
msg['To'],msg['Cc']= ",".join(receiveList), ",".join(andSendList)
msg['Subject'] = Header(_subJect, 'utf-8')
msg.attach(message)
if not _imgList is None:
for ig in _imgList: #加载图片,如果发生_imgList图片元组的传入,即判定为需要发送带图片的邮件
img = MIMEImage(open(ig, "rb").read())
fn = ig.split('\\')[-1] #获取带后缀的文件名,截取掉图片的路径
fn = fn.split('.')[0] #获取文件名,无后缀
img.add_header('Content-ID', fn)
msg.attach(img)
if not _attf is None:
for _af in _attf: #加载附件,如果不需要附件会自动跳过
fileApart = MIMEApplication(open(_af,"rb").read())
attFile = os.path.basename(_af)
fileApart.add_header("Content-Disposition","attachment",filename=Header(attFile,'utf-8').encode())
encoders.encode_base64(fileApart) #附件名如果是中文可能会乱码,可能需要解码
msg.attach(fileApart)
self.smtpObj.sendmail(self.mailUser, receiveList + andSendList+blindSendList, msg.as_string())
reCode, errMsg = True, "邮件发送成功"
except smtplib.SMTPServerDisconnected:
# 重复login会导致这个问题,如果已经成功登录了一个用户,再次改成不能登录的密码,就不能再次发起login
errMsg = "[Critical]登录频率过于频繁(服务器拒绝)..."
except ConnectionRefusedError:
errMsg = "[Error]邮箱服务器 %s:%s 连接失败!" % (self.host, self.port)
except smtplib.SMTPAuthenticationError:
errMsg = "[Error]账户名密码错误,无法登陆..."
except smtplib.SMTPException as e:
errMsg = "Error: 邮件发送失败:%s" % str(e)
except Exception as e:
raise e
return reCode,errMsg
if __name__=="__main__":
EMIC = emailObj("test@email.com", "1234567")
#邮件的内容,在我写的类里,如果要用图片,img的cid必须要等于图片的文件名一一对应
emailCont = '''
<p style="text-indent:2em; font-weight:bold;">您好,这是我发的测试邮件:</p>
<p><img src="cid:imgA"></p>
'''
imgfiles = ["/home/img/imgA.png"]
attfiles=["/home/附件1.pdf","/home/附件2.doc"]
state, Res = EMIC.sendMail(emailCont, _recv="接收者1@email.com;接收者2@email.com",
_ands="抄送者1@email.com;抄送者2@email.com",
_subJect="这是邮件的主题(标题)",
_imgList=imgfiles,
_attf=attfiles)
提醒一下,邮件支持的HTML格式是有限的,不支持javascript,最好使用内联CSS样式,css3(不包括3)版本以下的样式基本都是支持的。有兴趣的可以研究下HTML的基础,简单的发邮件来说HTML的基础知识是够用的。
一般都要测试Foxmail和Outlook的兼容问题(我就经常遇到两者收到的同样邮件格式不同的问题),反正大多是长宽比例等在不同邮箱上的失调。