python 构建和解析邮件
用python写传统的邮件
from email.mime.text import MIMEText message = ''' hello jason it is a test mail please accept it''' msg = MIMEText(message) msg['To'] = 'xxxxx@qq.com' msg['From'] = 'jason <mjzheng@xxxxx.com>' msg['Subject'] = 'test mail' print msg.as_string()
结果:
Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit To: xxxxx@qq.com From: jason <mjzheng@xxxxx.com> Subject: test mail hello jason it is a test mail please accept it
默认添加了3个头部Content-Type,MIME-Version,Content-Transfer-Encoding,而且也已经排好了版,这样的邮件,如果理解发送是可以的。如果想延迟发送的话,最好还是要加上Date和Message-ID头部,可以通过下面的方式来添加。
from email.mime.text import MIMEText from email import Utils message = ''' hello jason it is a test mail please accept it''' msg = MIMEText(message) msg['To'] = 'xxxxx@qq.com' msg['From'] = 'jason <mjzheng@xxxxx.com>' msg['Subject'] = 'test mail' msg['Date'] = Utils.formatdate(localtime=1) msg['Message-ID'] = Utils.make_msgid() print msg.as_string()
结果:
Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit To: xxxxx9@qq.com From: jason <mjzheng@xxxxx.com> Subject: test mail Date: Wed, 27 Mar 2013 11:48:59 +0800 Message-ID: <20130327034859.14284.670@ZGC-20121219ZKJ> hello jason it is a test mail please accept it
这样的邮件就可以正确的被发送了
解析邮件
import sys,email msg = email.message_from_file(sys.stdin) print "*** Headers in message: " for header,value in msg.items(): print header+":" print " "+value if msg.is_multipart(): print "mail is MIME type, can't resolve it." sys.exit(1) else: print "-" * 78 if 'subject' in msg: print "Subject: ",msg['subject'] print "-" * 78 print "Message body:" print print msg.get_payload()
把邮件显示结果写入到一个mail.txt文件中。
from email.mime.text import MIMEText from email import Utils message = ''' hello jason it is a test mail please accept it''' msg = MIMEText(message) msg['To'] = 'xxxxx@qq.com' msg['From'] = 'jason <mjzheng@xxxxx.com>' msg['Subject'] = 'test mail' msg['Date'] = Utils.formatdate(localtime=1) msg['Message-ID'] = Utils.make_msgid() fd = open('mail.txt','w') fd.write(msg.as_string()) fd.close()
通过这个把刚刚显示出来的邮件,以一种更可读的方式显示出来,如下图:
构造MIME邮件
上面说的都是些纯文本邮件,那么如何才能让邮件发送非纯文本邮件呢,这个就设计到了MIME,大家可以跟着到google查一下。
提几个重点步骤吧!
1. 建立一个MIMEMultipart()对象,设置邮件的header。
2.为邮件部分内容建立一个MIMEText()对象,把它放到MIMEMultipart()对象中。
3.为每一个附件,建立一个合适的MIME对象,也把他放到MIMEMultipart()对象中。
4.调用MIMEMultipart()对象中的as_string()函数来得到作为结果的邮件。
下面我们就用python来构造MIME格式的邮件,这个是可以添加附件的邮件格式。
email_mime.py
from email import Utils,Encoders import mimetypes,sys from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart from email.mime.base import MIMEBase def attachment(filename): fd = open(filename,'rb') mimetype,mimeencoding = mimetypes.guess_type(filename) if mimetype or (mimeencoding is None): mimetype = 'application/octet-stream' maintype,subtype = mimetype.split('/') if maintype == 'text': retval = MIMEText(fd.read(),_subtype=subtype) else: retval = MIMEBase(maintype,subtype) retval.set_payload(fd.read()) Encoders.encode_base64(retval) retval.add_header('Content-Disposition','attachment',filename = filename) fd.close() return retval message = ''' hello jason it is a test mail please accept it''' msg = MIMEMultipart() msg['To'] = 'xxxxx@qq.com' msg['From'] = 'jason <mjzheng@xxxxx.com>' msg['Subject'] = 'test mail' msg['Date'] = Utils.formatdate(localtime=1) msg['Message-ID'] = Utils.make_msgid() body = MIMEText(message) msg.attach(body) for filename in sys.argv[1:]: msg.attach(attachment(filename)) print msg.as_string()
运行脚本(这里添加了mail.txt和Loadrunner.rar作为附件):
python email_mime.py mail.txt Loadrunner.rar > results.txt
Content-Type: multipart/mixed; boundary="===============1228986135==" MIME-Version: 1.0 To: xxxxx@qq.com From: jason <mjzheng@xxxxx.com> Subject: test mail Date: Wed, 27 Mar 2013 14:31:02 +0800 Message-ID: <20130327063102.12588.91954@ZGC-20121219ZKJ> --===============1228986135== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit hello jason it is a test mail please accept it --===============1228986135== Content-Type: application/octet-stream MIME-Version: 1.0 Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="mail.txt" Q29udGVudC1UeXBlOiB0ZXh0L3BsYWluOyBjaGFyc2V0PSJ1cy1hc2NpaSINCk1JTUUtVmVyc2lv bjogMS4wDQpDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiA3Yml0DQpUbzogeHh4eHhAcXEuY29t DQpGcm9tOiBqYXNvbiA8bWp6aGVuZ0B4eHh4eC5jb20+DQpTdWJqZWN0OiB0ZXN0IG1haWwNCkRh dGU6IFdlZCwgMjcgTWFyIDIwMTMgMTI6NTU6MTMgKzA4MDANCk1lc3NhZ2UtSUQ6IDwyMDEzMDMy NzA0NTUxMy4xMzc1Mi4xNTU1NkBaR0MtMjAxMjEyMTlaS0o+DQoNCiBoZWxsbyBqYXNvbg0KaXQg aXMgYSB0ZXN0IG1haWwNCnBsZWFzZSBhY2NlcHQgaXQ= --===============1228986135== Content-Type: application/octet-stream MIME-Version: 1.0 Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="Loadrunner.rar" UmFyIRoHAM+QcwAADQAAAAAAAAADJXRAgiwAa0EBAADwAwACkyympH2W+TAdMwwAIAAAAGxtNzAu ZGxsAAHABhgl1VUMiNXgGmIzJMkmAYExbBsVistY2naRtlsg0LA7YVMAVMTI4OYRSBFoFxyi0UzG lUgwcmNmHDGnWjaPaFpbR7Ttp37TvaFuWojBDpIVlCVSpGkaxtlt5LmVYqdGNYGfn3esnqzMmtb3 zmeiQG1759/X+NpM5zfN+rWtb1vW9a1vXOfxLX/CefP98+b1vet89MzOYeeL+j/7TGYAFAACay42 ...
构造成功。
注意这里的Content-Type(内容类型)和Content-Transfer-Encoding(内容传输编码格式)的变化
但是呢,有个问题就是为什么mail.txt文件为什么识别不了呢,应该识别成功text/plian的内容格式啊。
查了一下,发现mimetypes模块是通过调用mimetypes.pyc文件的,查看一下mimetypes.py文件
可以看到
knownfiles = [ "/etc/mime.types", "/etc/httpd/mime.types", # Mac OS X "/etc/httpd/conf/mime.types", # Apache "/etc/apache/mime.types", # Apache 1 "/etc/apache2/mime.types", # Apache 2 "/usr/local/etc/httpd/conf/mime.types", "/usr/local/lib/netscape/mime.types", "/usr/local/etc/httpd/conf/mime.types", # Apache 1.2 "/usr/local/etc/mime.types", # Apache 1.3 ]
因为我是在windows环境下运行的,所以当然找不到所识别的mime类型啦