python练习--发送html格式邮件且发送附件;

最近需要些一个根据配置自动获取html正文及附件的工具脚本。随业余时间写了这个脚本,同时也是对邮件结构的一个学习;后续还需要继续完善html内容生成的部分

感觉脚本还可以优化,比如可以加入图片部分,pdf等,另外发送邮件用的默认铭文方式。没有采用加密/SSL等其他方式;

另外xml配置部分的提取还可以使用字典来做。这样可以更优一些;

代码:

xml配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<Email>
    <EmailServerConf>
        <!-- smtp配置 :只支持1个-->
        <smtp  ip="email ip" port="25" user="abc" password="defdd" />
    </EmailServerConf>
    <!-- 发件人:只支持1个 -->
    <From address="abc@123.com" />
    <!-- 收件人:支持多个 -->
    <ToEmailList>
        <To address="abc@123.com" />
    </ToEmailList>
    <!-- 抄送:支持多个 -->
    <CCEmailList>
        <CC address="abc@123.com" />
    </CCEmailList>
    <!-- 邮件主题:只支持1个 -->
    <Subject title="This is for test!" />
    <!-- 邮件正文:只支持1个,html格式,无图片 -->
    <Emailcomment>
        <comment file="C:UsersaaaDesktopMultipart.html" />
    </Emailcomment>
    <!-- 邮件附件:支持多个 -->
    <EmailAttach>
        <attach file="C:UsersaaaDesktopMultipart.html" />
    </EmailAttach>
</Email>
    

python部分:

#! /usr/bin/env python
#coding:utf-8

import os,string,sys
import smtplib
from email.MIMEMultipart import MIMEMultipart
from email import Utils
from email.MIMEBase import MIMEBase
from email import encoders
from xml.dom import minidom
import logging
from email.mime.text import MIMEText

class CommEmail(object):
    
    
    emailConf = r"D:workspacecar	oolsemailconf.xml"
    
    def __init__(self):
        
        #init 
        self.sIp = ""
        self.sPort = ""
        self.sUser = ""
        self.sPassword = ""
        self.fEmailServerConfFile = ""
        self.fEmailTemplateFile = ""
        self.sEmailOwner = ""
        self.dEmailTo = []
        self.dEmailCC = []
        self.dattach = []
        self.sSubject = ""
        self.emComment = ""
        self.tDate = Utils.formatdate(localtime = 1)      
        logging.basicConfig(level=logging.DEBUG,
                            format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
                            datefmt='%a, %d %b %Y %H:%M:%S',
                            filename='Email.log',
                            filemode='a')
        
        #from conf-profile to set email-server  configure
        self.fEmailServerConfFile = self.emailConf
        try:
            #tag handle
            xmlFeed = minidom.parse(self.fEmailServerConfFile)               
            xmlEmaiSMTP = xmlFeed.getElementsByTagName('smtp')            
            xmlEmailFrom = xmlFeed.getElementsByTagName('From')
            xmlEmaiTos = xmlFeed.getElementsByTagName('To')
            xmlEmaiCCs = xmlFeed.getElementsByTagName('CC')
            xmlEmailSubject = xmlFeed.getElementsByTagName('Subject')
            xmlEmailComments = xmlFeed.getElementsByTagName('comment')
            xmlEmailattachs = xmlFeed.getElementsByTagName('attach')
            
            #only one smtp-tag 
            for smtpConf in xmlEmaiSMTP:
                self.sIp = smtpConf.getAttribute("ip")
                self.sPort = smtpConf.getAttribute("port")
                self.sUser = smtpConf.getAttribute("user")
                self.sPassword = smtpConf.getAttribute("password")
                   
            #To    
            for To in xmlEmaiTos:   
                self.dEmailTo.append(To.getAttribute("address"))
            
            #CC   
            for cc in xmlEmaiCCs:   
                self.dEmailCC.append(cc.getAttribute("address"))
            
            #From & Subject             
            self.sEmailOwner = xmlEmailFrom[0].getAttribute("address")
            self.sSubject = xmlEmailSubject[0].getAttribute("title")
            
           
            self.emComment = open(xmlEmailComments[0].getAttribute("file")).read()
            
            #attach   
            for attach in xmlEmailattachs:   
                self.dattach.append(attach.getAttribute("file"))
            
            
            logging.info("smtp conf ====> ip: "+ self.sIp + " " + "port: " + self.sPort + " " + "user: " + self.sUser + " password: " + self.sPassword ) 
            logging.info("init end")
            
        except:
            logging.warning("ERROR: EmailServerConfFile is ERROR !!!")
            logging.warning("exit(1) from __init__")        
            exit(1)
        
    '''
    #for email-server test
    def testEmaileServer(self):
        emailHandle = smtplib.SMTP(self.sIp,int(self.sPort))
        emailHandle.login(self.sUser, self.sPassword)
        msg = "To: aaa@bb.com 
From: aaa@bb.com 
Subject:testing 
" #header
        msg = "
this is test msg

"       
        emailHandle.sendmail("aaa@bb.com", "aaa@bb.com", msg)
        emailHandle.quit()
        #logging.INFO(" Email for test was send." )
    '''
    
    #get html commtent


    #email comment & sendmail
    def sendHtmlEmail(self):
        try:
            msg = MIMEMultipart()
            msg["Subject"] = self.sSubject
            msg["From"] = self.sEmailOwner
            msg["To"] = ";".join(self.dEmailTo)  
            msg["CC"] = ";".join(self.dEmailCC)   
            msg["Date"] = self.tDate         

            #email comment
            emailComment = MIMEText(self.emComment,_subtype="html",_charset='base64')           
            #add eamil attach            
            for a in self.dattach:
                
                t =MIMEBase('application','octet-stream')
                t.set_payload(open(a,'r').read())
                encoders.encode_base64(t)
                t.add_header('Content-Disposition','attachment;filename="%s"' % os.path.basename(a))            
                msg.attach(t)
            
            msg.attach(emailComment)
            emailHandle = smtplib.SMTP()
            emailHandle.connect(self.sIp,int(self.sPort))
            emailHandle.login(self.sUser, self.sPassword)
            emailHandle.sendmail(msg["From"], msg["To"], msg.as_string())
            emailHandle.quit()
            emailHandle.close()
            logging.info(" Email for test was send." )
            logging.info("makeMIMETextEmail ok")
            
        except:
            logging.warning("ERROR: makeMIMETextEmail is ERROR !!!")
            logging.warning("exit(1) from makeMIMETextEmail")        
            exit(1)
            
if __name__ == "__main__":
    a = CommEmail()
    a.makeMIMETextEmail()

smtp协议参考文章:

这个东西这里只用来了解,没有详细学习;有问题可以参考下列文章:

http://blog.csdn.net/kerry0071/article/details/28604267

http://blog.csdn.net/bripengandre/article/details/2191048

邮件结构简述:

a、邮件结构可以通过查看邮件源码看到。可以看到邮件其实也是类似http请求一样。有包头,body等;在python中的对应类和方法大多数也是采用hash字典来操作;

b、python中各MIME类的继承结构:

MIMEBase
    |-- MIMENonMultipart
        |-- MIMEApplication
        |-- MIMEAudio
        |-- MIMEImage
        |-- MIMEMessage
        |-- MIMEText
    |-- MIMEMultipart

c、各种多媒体格式可以通过MIMEBse类来构造。在头部加入application/octet-stream ,即2进制文件。其实就是MIMEApplication类,让客户端自己根据附件的扩展名判断需要用什么来解析;

参考文章:

http://blog.csdn.net/handsomekang/article/details/9811355  ------ 各种类型附件发送方法

不会炒菜的非专业测试人员
原文地址:https://www.cnblogs.com/carterzhang/p/4190065.html