最近需要些一个根据配置自动获取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="[email protected]" /> <!-- 收件人:支持多个 --> <ToEmailList> <To address="[email protected]" /> </ToEmailList> <!-- 抄送:支持多个 --> <CCEmailList> <CC address="[email protected]" /> </CCEmailList> <!-- 邮件主题:只支持1个 --> <Subject title="This is for test!" /> <!-- 邮件正文:只支持1个,html格式,无图片 --> <Emailcomment> <comment file="C:\Users\aaa\Desktop\Multipart.html" /> </Emailcomment> <!-- 邮件附件:支持多个 --> <EmailAttach> <attach file="C:\Users\aaa\Desktop\Multipart.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:\workspace\car\tools\emailconf.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.putcmd("vrfy", "[email protected]") #emailHandle.getreply() emailHandle.login(self.sUser, self.sPassword) msg = "To: [email protected] \nFrom: [email protected] \nSubject:testing \n" #header msg = "\nthis is test msg\n\n" emailHandle.sendmail("[email protected]", "[email protected]", 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 ------ 各种类型附件发送方法