处理eml文件,一般windows下会启用默认的outlook来阅读,实际上python的email模块可以很简单的实现对eml文件的阅读,闲来木事,利用wxpython制作了一个eml文件阅读器,实现了对eml文件正文的阅读和附件的阅读,但由于制作时,在信头读取部分使用了label,在格式处理时未处理好,当信件有多个收件人时,会出现格式混乱。另外,附件如果有多个,只会显示最后一个。哪位感兴趣或者有时间可以自己改一下。
    一、email模块对eml文件的读取
    首先先来看一个邮件的源文件:
Received: from 192.168.208.56 ( 192.168.208.56 [192.168.208.56] ) by
ajax-webmail-wmsvr37 (Coremail) ; Thu, 12 Apr 2007 12:07:48 +0800 (CST)
Date: Thu, 12 Apr 2007 12:07:48 +0800 (CST)
From: user1 <xxxxxxxx@163.com>
To: user2 <YYYY@163.com>
Message-ID: <31571419.200911176350868321.JavaMail.root@bj163app37.163.com>
Subject: =?gbk?B?u+nJtA==?=
MIME-Version: 1.0
Content-Type: multipart/Alternative;
boundary="----=_Part_21696_28113972.1176350868319"

------=_Part_21696_28113972.1176350868319
Content-Type: text/plain; charset=gbk
Content-Transfer-Encoding: base64

ztLS0b+qyrzS1M6qysfSu7j20MfG2ru70ru0zqOs1K3AtMrH0ru49tTCtffSu7TOztLDx8/W1NrT
prjDysew67XjssXE3MjI1ebC6bezICAg
------=_Part_21696_28113972.1176350868319
Content-Type: text/html; charset=gbk
Content-Transfer-Encoding: quoted-printable

<DIV>=CE=D2=D2=D1=BF=AA=CA=BC=D2=D4=CE=AA=CA=C7=D2=BB=B8=F6=D0=C7=C6=DA=BB=
=BB=D2=BB=B4=CE=A3=AC=D4=AD=C0=B4=CA=C7=D2=BB=B8=F6=D4=C2=B5=F7=D2=BB=B4=CE=
</DIV>
<DIV>=CE=D2=C3=C7=CF=D6=D4=DA=D3=A6=B8=C3=CA=C7=B0=EB=B5=E3=B2=C5=C4=DC=C8=
=C8</DIV>
<DIV>=D5=E6=C2=E9=B7=B3</DIV>
------=_Part_21696_28113972.1176350868319--
    从第一行到第一个空行之间的为信件头,后面的是信件体。通过outlook解码后,正文显示为:
我已开始以为是一个星期换一次,原来是一个月调一次
我们现在应该是半点才能热
真麻烦

下面,具体来看看email模块的使用。
(1)打开eml文件,利用open语句,具体与打开其它文件一样,如fileopen=open('AAA.eml','r')。
(2)email.message_from_file()创建message对象,此时会对fileopen内容进行初步解码。如msg = email.message_from_file(fileopen)
(3)获取信件主题subject = msg.get("subject"),此时主题中含有 =?gbk?B?u+nJtA==?=这样的编码,以下代码用来解码

h = email.Header.Header(subject)
dh = email.Header.decode_header(h)
subject = dh[0][0]

解码后,正常显示为“婚纱”

(4)解析发件人和收件人,发件人往往只有一个,所以可以直接用efrom=email.utils.parseaddr(msg.get("from"))[1]进行解析,收件人有时会有多个,可得用以下代码:

for tolines in msg.get("to").splitlines():
findst=tolines.find('<') #从to中找<位置
if findst==-1:#判断是否只有一个收件人,当tolines中不含有'<'时,只存在一个收件人eto=email.utils.parseaddr(msg.get("to"))[1]
else:eto=eto+tolines[findst:]+'\n'

(5)解析时间,etime=msg.get("date"),显示时间格式为Thu, 12 Apr 2007 12:07:48 +0800 (CST),这里可以再根据需要转换为2007年4月12日星期四 12:07。

(6)解析正文和附件,代码如下:

for bodycheck in msg.walk():if not bodycheck.is_multipart():                    psname = bodycheck.get_param("name")

if psname:                        psh = email.Header.Header(psname)                        psdh = email.Header.decode_header(psh)                        psfname = psdh[0][0]

                        data = bodycheck.get_payload(decode=True) 

try:                            f = open(psfname, 'wb')except:#                            f = open('tempps', 'wb')

                        f.write(data)                        f.close()else:                        data=bodycheck.get_payload(decode=True)                        p=str(data)

  

这里,邮件正文保存为p,str类型,附件文件名为psfname,并将附件保存在当前文件+下面。如果有多个附件都会保存在这里。
(7)关闭文件fp.close()

二、wxpython制作GUI
(1)self.staticText1、self.textCtrl1、self.button1三个控件完成对eml文件的选取。点击self.button1后,利用wxfiledialog调取文件选择框,限定wildcard = "note source (*.eml)|*.eml",由于路径有时会出现中文错误,所以使用了encode('utf-8')进行编码。

def OnButton1Button(self, event): #浏览dialog = wx.FileDialog(None, "Choose a file", os.getcwd(),"", wildcard, wx.OPEN)if dialog.ShowModal() == wx.ID_OK:aa=dialog.GetPath().encode('utf-8')self.textCtrl1.SetValue(aa.decode('utf-8'))self.reademail()dialog.Destroy()event.Skip()

  

(2)利用self.htmlWindow1显示邮件正文。邮件正文读取后一般都是html代码,通过htmlWindow1进行正常显示。
(3)实现邮件的另存为txt。邮件另存为txt时,遇到的主要问题是如何将html代码转换为带格式的txt文档,于是利用了正则和字符串的替换,替换为\n换行,然后又去掉了多余的换行,具体代码如下:

def savetotxt(self,filena):#邮件另存为txt文件        resultfile=''        read=file('temps').read()         readf_con=read.replace('&nbsp;','\n')         readf_con=readf_con.replace('»','\n')        readf_con=re.sub("<!--.+?-->",'\n',readf_con)         readf_con=re.sub("<.*?>",'\n',readf_con)        readf_con=re.sub('\n+','\n',readf_con)for tt in readf_con.splitlines():            tt=tt.rstrip()+'\n'            resultfile=resultfile+tt  #去除temps文件中多余的空行

        w=open(filena,'w')

        w.write(resultfile)         w.close()

目前该代码存在的主要问题是:
1、收件人很多时,窗口格式会发生错乱
2、附件有多个时,只能显示一个
3、eml另存为时,附件只能保存最后一个
有兴趣的朋友可以自行修改一下。

完整代码如下:

#-*- encoding: gb2312 -*-'''eml阅读器 V1.0小五义:http://www.cnblogs.com/xiaowuyi仍然存在问题:1、收件人很多时,窗口格式会发生错乱2、附件有多个时,只能显示一个3、eml另存为时,附件只能保存一个'''

import wximport wx.htmlimport osimport emailimport reimport shutil

wildcard = "note source (*.eml)|*.eml"psfname='无'  #附件名

def create(parent):return Frame1(parent)

[wxID_FRAME1, wxID_FRAME1BUTTON1, wxID_FRAME1PANEL1, wxID_FRAME1STATICTEXT1, wxID_FRAME1STATICLINE1, wxID_FRAME1STATICTEXT2, wxID_FRAME1STATICTEXT3,wxID_FRAME1TEXTCTRL1, wxID_FRAME1HTMLWINDOW1,wxID_FRAME1BUTTON2] = [wx.NewId() for _init_ctrls in range(10)]

class Frame1(wx.Frame):def _init_ctrls(self, prnt):

        wx.Frame.__init__(self, id=wxID_FRAME1, name='', parent=prnt,              pos=wx.Point(269, 142), size=wx.Size(899, 599),              style=wx.DEFAULT_FRAME_STYLE, title='Eml文件阅读器 V1.0')        self.SetClientSize(wx.Size(891, 565))        self.Enable(True)        self.SetIcon(wx.Icon(u'mb_4.ico', wx.BITMAP_TYPE_ICO))  #当前目录下放一个名为mb_4.ico的文件做图标

        self.panel1 = wx.Panel(id=wxID_FRAME1PANEL1, name='panel1', parent=self,              pos=wx.Point(0, 0), size=wx.Size(891, 565),              style=wx.TAB_TRAVERSAL)

        self.textCtrl1 = wx.TextCtrl(id=wxID_FRAME1TEXTCTRL1, name='textCtrl1',              parent=self.panel1, pos=wx.Point(120, 16), size=wx.Size(632, 23),              style=0, value=u'')        self.textCtrl1.SetEditable(False)

        self.button1 = wx.Button(id=wxID_FRAME1BUTTON1, label=u'浏览',              name='button1', parent=self.panel1, pos=wx.Point(776, 16),              size=wx.Size(75, 23), style=0)        self.button1.SetFont(wx.Font(11, wx.SWISS, wx.NORMAL, wx.BOLD, False,              u'Tahoma'))        self.button1.Bind(wx.EVT_BUTTON, self.OnButton1Button,              id=wxID_FRAME1BUTTON1)

        self.staticText1 = wx.StaticText(id=wxID_FRAME1STATICTEXT1,              label=u'文件名:', name='staticText1', parent=self.panel1,              pos=wx.Point(45, 16), size=wx.Size(56, 23), style=0)        self.staticText1.SetFont(wx.Font(11, wx.SWISS, wx.NORMAL, wx.BOLD, False,              u'Tahoma'))

        self.htmlWindow1 = wx.html.HtmlWindow(id=wxID_FRAME1HTMLWINDOW1,              name='htmlWindow1', parent=self.panel1, pos=wx.Point(72, 186),              size=wx.Size(747, 300), style=wx.html.HW_SCROLLBAR_AUTO|wx.DOUBLE_BORDER)

        self.staticText2 = wx.StaticText(id=wxID_FRAME1STATICTEXT2,              label=u' 发件人:\n 日    期:\n 收件人:\n 主    题:\n', name='staticText2', parent=self.panel1,              pos=wx.Point(72, 80), size=wx.Size(747, 90), style=wx.html.HW_SCROLLBAR_AUTO)        self.staticText2.SetFont(wx.Font(11, wx.SWISS, wx.NORMAL, wx.BOLD, False,              u'Tahoma'))

        self.staticText3 = wx.StaticText(id=wxID_FRAME1STATICTEXT3,              label=u' 附    件:', name='staticText3', parent=self.panel1,              pos=wx.Point(72, 496), size=wx.Size(680, 14), style=0)        self.staticText3.SetFont(wx.Font(11, wx.SWISS, wx.NORMAL, wx.BOLD, False,              u'Tahoma'))

        self.staticLine1 = wx.StaticLine(id=wxID_FRAME1STATICLINE1,              name='staticLine1', parent=self.panel1, pos=wx.Point(0, 55),              size=wx.Size(891, 2), style=0)

        self.button2 = wx.Button(id=wxID_FRAME1BUTTON2, label=u'导出',              name='button2', parent=self.panel1, pos=wx.Point(776, 496),              size=wx.Size(75, 23), style=0)        self.button2.SetFont(wx.Font(11, wx.SWISS, wx.NORMAL, wx.BOLD, False,              u'Tahoma'))        self.button2.Bind(wx.EVT_BUTTON, self.OnButton2Button,              id=wxID_FRAME1BUTTON2)

def __init__(self, parent):        self._init_ctrls(parent)

def reademail(self):#read email        global psfname        checkfile=True        p=''  #记录邮件html正文        txtemail=''#记录邮件txt正文        eto=''

        filename=self.textCtrl1.GetValue()try:            emailfile=open(filename,'rb')            msg=email.message_from_file(emailfile)            subject=msg.get('subject')            head=email.Header.Header(subject)            dhead=email.Header.decode_header(head)            subject=dhead[0][0]            efrom=email.utils.parseaddr(msg.get("from"))[1]            etime=msg.get("date")#判断收件人个数

print msg.get("to")for tolines in msg.get("to").splitlines():                findst=tolines.find('<')  #从to中找<位置                if findst==-1:                    eto=email.utils.parseaddr(msg.get("to"))[1]else:                    eto=eto+tolines[findst:]+'\n'

#eto=email.utils.parseaddr(msg.get("to"))[1]            ehead=' 发件人:'+efrom+'\n'+' 日   期:'+etime+'\n'+' 收件人:'+eto+'\n'+' 主   题:'+subject+'\n'

for bodycheck in msg.walk():if not bodycheck.is_multipart():                    psname = bodycheck.get_param("name")

if psname:                        psh = email.Header.Header(psname)                        psdh = email.Header.decode_header(psh)                        psfname = psdh[0][0]

                        data = bodycheck.get_payload(decode=True) 

try:                            f = open(psfname, 'wb')except:#                            f = open('tempps', 'wb')

                        f.write(data)                        f.close()else:                        data=bodycheck.get_payload(decode=True)                        p=str(data)

            emailend=ehead            self.staticText2.SetLabel(emailend)            self.staticText3.SetLabel(' 附    件:'+psfname)

            self.htmlWindow1.SetPage(p)            txtemail=emailend+'正文:'+p            checkfile=Falseexcept:

            tishi='文件'+'格式错误!'            wx.MessageBox(tishi,'注意',wx.OK)        

        tem=open('temps','w')   # 临时文件存放

        lamp='<DIV>'+txtemail+'</DIV><DIV>'+' 附    件:'+psfname        lamp=lamp.replace('\n','</DIV><DIV>')        tem.write(lamp)

        tem.close()       

def OnButton1Button(self, event):  #浏览        dialog = wx.FileDialog(None, "Choose a file", os.getcwd(),"", wildcard, wx.OPEN)if dialog.ShowModal() == wx.ID_OK:            aa=dialog.GetPath().encode('utf-8')            self.textCtrl1.SetValue(aa.decode('utf-8'))            self.reademail()        dialog.Destroy()        event.Skip()

def savetotxt(self,filena):#邮件另存为txt文件        resultfile=''        read=file('temps').read()         readf_con=read.replace('&nbsp;','\n')         readf_con=readf_con.replace('»','\n')        readf_con=re.sub("<!--.+?-->",'\n',readf_con)         readf_con=re.sub("<.*?>",'\n',readf_con)        readf_con=re.sub('\n+','\n',readf_con)for tt in readf_con.splitlines():            tt=tt.rstrip()+'\n'            resultfile=resultfile+tt  #去除temps文件中多余的空行

        w=open(filena,'w')

        w.write(resultfile)         w.close()

def OnButton2Button(self, event):#eml另存为        wid = "text file (*.txt)|*.txt"        savedialog = wx.FileDialog(None, "Choose a file", os.getcwd(),"", wid, wx.SAVE)if savedialog.ShowModal() == wx.ID_OK:            fil=savedialog.GetPath().encode('utf-8')        savef=fil.decode('utf-8')        savedialog.Destroy()        savep=os.path.dirname(savef)

#将附件另存到该目录下        checkdot=psfname.find('.')if checkdot!= -1:#判断是否存在附件            kzhname='ps'+psfname[checkdot:]            psfile=os.path.join(savep,kzhname)            shutil.copy(psfname, psfile)        self.savetotxt(savef)#存eml正文

        event.Skip()

class App(wx.App):def OnInit(self):        self.main=create(None)        self.main.Show()        self.SetTopWindow(self.main)return Truedef main():    application=App(0)    application.MainLoop()

if __name__=='__main__':    main()

转载于:https://www.cnblogs.com/xiaowuyi/archive/2012/04/05/2432862.html

wxpython制作eml文件阅读器相关推荐

  1. wxpython制作桌面悬浮球

    介绍 使用wxpython制作一个类似于电脑管家一样的悬浮球. 功能 圆形窗口 自动鼠标离开悬浮球自动贴边 鼠标在悬浮球上自动弹出整个悬浮球 效果 代码 import wxclass myframe( ...

  2. monkey开源工具Linux,wxPython制作跑monkey工具(Python3)

    一. wxPython制作跑monkey工具python文件源代码内容Run Monkey.py如下: #!/usr/bin/env python import wx import os import ...

  3. wxpython制作表格界面_wxpython入门第二步(布局)

    一个典型的应用程序由各种小组件组成.这些组件被放置在容器里面.程序员必须管理应用程序的布局.在 wxPython 中,可以使用绝对定位或使用 sizer 来布局小组件. 绝对定位 程序员以像素为单位指 ...

  4. wxpython制作表格界面_[Python] wxPython 菜单栏控件学习总结(原创)

    1.总结 1.大体创建过程 1.创建一个 菜单栏 : menuBar = wx.MenuBar() 相当于这个白色地方,没有File这个菜单 2.创建 菜单 : fileMenu = wx.Menu( ...

  5. wxpython制作表格界面_Python wxPython库使用wx.ListBox创建列表框示例

    本文实例讲述了Python wxPython库使用wx.ListBox创建列表框.分享给大家供大家参考,具体如下: 如何创建一个列表框? 列表框是提供给用户选择的另一机制.选项被放置在一个矩形的窗口中 ...

  6. wxpython制作excel表格_怎么做一个精美的excel表格

    你还在制作平平无奇的表格吗,是时候做出改变啦.下面为你展示了详细的操作步骤,看完之后就再也不要做普通的表格了,尝试着设计更多的样式来为你的表格添彩吧!一起看下去吧! 制作步骤: 1.整理表格 把字体设 ...

  7. wxpython制作金山快盘自动签到程序

    首先感谢龙昌在http://www.oschina.net/code/snippet_93572_10721发布的金山快盘自动签到程序代码,本人在此基础上,利用wxpython做了一个程序,具体代码如 ...

  8. wxpython制作抽奖页面

    目录 杂话(解释) 全代码 上才艺. 最近需要编写一个抽奖的小玩意,但是查了一下网上使用wxpython的方法似乎不是很多,遂自己研究了一下. 杂话(解释) 以下是需要用到的一些库 import im ...

  9. 用wxpython 制作出入库 进销存 ERP 仓库管理系统 可导出Excel

    借鉴 crazeblade 开发 新增查询库存 登录页面 类别 物品出入库 流水账 报表功能 导出Excel 新增物品库存查询 学习交流QQ 1270879157

最新文章

  1. android 动画x轴旋转,Android Roate3dAnimation实现围绕y轴竖直方向或者绕x轴方向旋转的3d动画效果...
  2. svg图片怎么存手机上_一张普通的图片,是怎么让安卓手机死机的?
  3. java获取年初年末_Java用于取得当前日期相对应的月初,月末,季初,季末,年初,年末时间...
  4. PHP的抽象类的一段简单代码示例
  5. SpringIOC容器中Bean的生命周期
  6. 人的一生能交多少朋友?
  7. Teleport 开源堡垒机的使用
  8. bean交个spring和new比较区别
  9. python中怎么精确20位_Python中的精确处理
  10. iOS开发 - 抛出异常
  11. 232 Crossword Answers
  12. 计算机联锁系统硬件结构,计算机联锁系统各部硬件.ppt
  13. mac安装旺旺启动台找不到_送修Mac前 万能的两个自救方法:重置 NVRAM(PRAM)与 重置 SMC...
  14. matlab图片测量尺寸_matlab尺寸测量
  15. 小米摄像头结合samba共享存储实现视频实时转存
  16. 学习July博文总结——支持向量机(SVM)的深入理解(下)
  17. 魔方机器人大赛——魔方步骤转换算法
  18. c语言上交源代码怎么交啊,C语言问题在线等啊作业提交上交的的内容必须由以下两个部分组成,缺 爱问知识人...
  19. 【大咖专栏】如何配置CEPH RGW对象存储与公有云同步
  20. 并发------多线程安全

热门文章

  1. Pytorch Note1 Pytorch介绍
  2. threeJs 入门篇
  3. pg数据库json数据类型_科学网—如何使用PostgreSQL中的JSONB数据类型(PG JSON系列2) - 孙鹏的博文...
  4. 说说 Spring Bean 的实例化过程?面试必问
  5. python定义一个复数类complex、内有两个成员变量_python应用(5):变量类型与数据结构...
  6. IDEA使用EasyCode一键生成CURD
  7. 百度编辑器上传失败问题--转码问题mb_convert_encoding与iconv
  8. 一、微信小程序集成Vant Weapp
  9. 全志V3S嵌入式驱动开发(看原理图)
  10. typescript往window挂载属性