通过python3发送各种邮件[实用版本]

邮件其实是支持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的兼容问题(我就经常遇到两者收到的同样邮件格式不同的问题),反正大多是长宽比例等在不同邮箱上的失调。

上一篇:python socket基本语法


下一篇:python之利用socket模块实现通信,模拟ftp部分功能