Python通过IMAP实现邮箱客户端

Python通过IMAP实现邮箱客户端,第1张

概述在日常工作生活中,都是利用个人或公司的邮箱客户端进行收发邮件,那么如何打造一款属于自己的邮箱客户端呢?本文以一个简单的小例子,简述如何通过Pyhton的imaplib和email两大模块,实现邮件的接 概述

在日常工作生活中,都是利用个人或公司的邮箱客户端进行收发邮件,那么如何打造一款属于自己的邮箱客户端呢?本文以一个简单的小例子,简述如何通过Pyhton的imaplib和email两大模块,实现邮件的接收并展示,仅供学习分享使用,如有不足之处,还请指正。

什么是IMAP?

IMAP,即Internet Message Access Protocol(互联网邮件访问协议),您可以通过这种协议从邮件服务器上获取邮件的信息、下载邮件等。IMAP与POP类似,都是一种邮件获取协议。

IMAP和POP有什么区别?

POP允许电子邮件客户端下载服务器上的邮件,但是您在电子邮件客户端的 *** 作(如:移动邮件、标记已读等),这是不会反馈到服务器上的,比如:您通过电子邮件客户端收取了QQ邮箱中的3封邮件并移动到了其他文件夹,这些移动动作是不会反馈到服务器上的,也就是说,QQ邮箱服务器上的这些邮件是没有同时被移动的 。但是IMAP就不同了,电子邮件客户端的 *** 作都会反馈到服务器上,您对邮件进行的 *** 作(如:移动邮件、标记已读等),服务器上的邮件也会做相应的动作。也就是说,IMAP是“双向”的。

同时,IMAP可以只下载邮件的主题,只有当您真正需要的时候,才会下载邮件的所有内容。

如何设置IMAP服务的SSL加密方式?

使用SSL的通用配置如下:

接收邮件服务器:imap.qq.com,使用SSL,端口号993
发送邮件服务器:smtp.qq.com,使用SSL,端口号465或587
账户名:您的QQ邮箱账户名(如果您是VIP帐号或Foxmail帐号,账户名需要填写完整的邮件地址)
密码:您的QQ邮箱密码
电子邮件地址:您的QQ邮箱的完整邮件地址

涉及知识点

在本示例中,涉及知识点如下所示:

imaplib模块:此模块实现通过IMAP【Internet Message Access Protocol,信息交互访问协议】协议进行邮箱的登录,接收和发送等功能。IMAP4_SSL(host='',port=IMAP4_SSL_PORT),通过此方法可以定义一个IMAP对象,需要对应的服务器和端口号。login(self,user,password),通过此方法实现对应邮箱的登录,传入指定的账号,密码即可。select(self,mailBox='INBox',Readonly=False) 选择收件箱search(self,charset,*criteria) 查找获取邮箱数据fetch(self,message_set,message_parts) 通过邮件编号,查找具体的邮件内容email模块:此模块主要用于邮件的解析功能message_from_string(s,*args,**kws) , 获取解析数据消息体email.header.decode_header(msg.get('Subject'))[0][1] 解析编码方式email.header.decode_header(msg.get('Date')) 解析邮件接收时间email.header.decode_header(msg.get('From'))[0][0] 解析发件人email.header.decode_header(msg.get('Subject'))[0][0].decode(msgCharset) 解析邮件标题email.utils.parseaddr(msg.get('Content-transfer-encoding'))[1] 解析邮件传输编码示例效果图

示例分为两部分,左边是邮件列表,右边是邮件内容,如下所示:

 

核心代码

邮件帮助类,主要包括邮件的接收,具体邮件内容的解析等功能,如下所示:

  1 import imaplib  2  email  3  datetime  4    5    6 class EmailUtil:  7     """  8     Email帮助类  9      10     host = 'imap.qq.com'  # 主机IP或者域名 11     port = 993 端口 12     username = ******** 用户名 13     password = ************** 密码或授权码 14     imap = None   邮箱连接对象 15   16      mail_Box = '**************'  # 邮箱名 17   18     def __init__(self,host,port): 19         """初始化方法 20         self.host = host 21         self.port = port 22          初始化一个邮箱链接对象 23         self.imap = imaplib.IMAP4_SSL(host=self.host,port=int(self.port)) 24   25     def login(self,username,password): 26         登录 27         self.username = username 28         self.password = password 29         self.imap.login(user=self.username,password=self.password) 30   31      get_mail(self): 32         获取邮件 33          self.mail_Box = mail_Box 34         email_infos = [] 35         if self.imap is not None: 36             self.imap.select(Readonly=False) 37             typ,data = self.imap.search(None,ALL')   返回一个元组,data为此邮箱的所有邮件数据 38               数据格式 data =  [b'1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18'] 39             if typ == OK': 40                 for num in data[0].split(): 41                     if int(num) > 10 42                          超过20,退出循环,不输出 43                         break 44                     typ1,data1 = self.imap.fetch(num,1)">(RFC822) 通过邮箱编号和选择获取数据 45                     if typ1 ==  46                         print(**********************************begin******************************************) 47                         msg = email.message_from_string(data1[0][1].decode("utf-8"))   用email库获取解析数据(消息体) 48                          获取邮件标题并进行进行解码,通过返回的元组的第一个元素我们得知消息的编码 49                         msgCharset = email.header.decode_header(msg.get(Subject'))[0][1] 50                          print('msg = ',msg) 51                          print('msgCharset= ',msgCharset)  # gb2312 52                         recv_date = self.get_email_date(email.header.decode_header(msg.get(Date))) 53                         mail_from = email.header.decode_header(msg.get(From))[0][0] 54                         if type(mail_from) == bytes: 55                             mail_from = mail_from.decode(msgCharset) 56   57                         mail_to = email.header.decode_header(msg.get(To 58                         subject = email.header.decode_header(msg.get('))[0][0].decode(msgCharset)   获取标题并通过标题进行解码 59   60                         Message %s\n%s\n" % (num,subject))   打印输出标题 61                         mail_from:' + mail_from +  mail_to:' + mail_to +  recv_date:' + str(recv_date)) 62                          # 邮件内容 63                          for part in msg.walk(): 64                              if not part.is_multipart(): 65                                  name = part.get_param("name") 66                                  if not name:  # 如果邮件内容不是附件可以打印输出 67                                      print(part.get_payload(decode=True).decode(msgCharset)) 68                          print('***********************************end*****************************************') 69                         email_info = { 70                             num": num, 71                             subject: subject,1)"> 72                             recv_date: recv_date,1)"> 73                             mail_to: mail_to,1)"> 74                             mail_from: mail_from 75                         } 76                         email_infos.append(email_info) 77         else 78             请先初始化并登录 79         return email_infos 80   81      get_email_content(self,num): 82         content = None 83         typ1,1)"> 84          85              86             msg = email.message_from_string(data1[0][1].decode( 87             print(msg) 88              89             msgCharset = email.header.decode_header(msg.get( 90              transfer_enCoding = email.header.decode_header(msg.get('Content-transfer-encoding')) 91             transfer_enCoding = email.utils.parseaddr(msg.get(Content-transfer-encoding'))[1 92             transfer_enCoding:,transfer_enCoding) 93             charset: 94              邮件内容 95             for part  msg.walk(): 96                 if  part.is_multipart(): 97                     name = part.get_param(name 98                     not name:   如果邮件内容不是附件可以打印输出 99                         if transfer_enCoding == 8bit100                             content = part.get_payload(decode=101                         102                             content = part.get_payload(decode=True).decode(msgCharset)103  104             (content)105             ***********************************end*****************************************106          content107  108      get_email_date(self,date):109         获取时间110         utcstr = date[0][0].replace(+00:00',1)">''111         utcdatetime =112         localtimestamp =113         try114             utcdatetime = datetime.datetime.strptime(utcstr,1)">%a,%d %b %Y %H:%M:%s +0000 (GMT)115             localdatetime = utcdatetime + datetime.timedelta(hours=+8116             localtimestamp = localdatetime.timestamp()117         except118             119                 utcdatetime = datetime.datetime.strptime(utcstr,%d %b %Y %H:%M:%s +0800 (CST)120                 localtimestamp = utcdatetime.timestamp()121             122                 utcdatetime = datetime.datetime.strptime(utcstr,%d %b %Y %H:%M:%s +0800123                 localtimestamp =124          localtimestamp125  126  127 if __name__ == __main__128     host = 129     port = 130     username = 131     password =  密码132     mail_Box =  邮箱名133     eamil_util = EmailUtil(host=host,1)">port)134     eamil_util.login(username=username,1)">password)135     eamil_util.get_mail()136     done')

邮件展示类,主要用于邮件内容在前台页面的展示,如下所示:

 1 from tkinter import * 2 from tkinterIE.tkinterIE  WebVIEw 3 from test_email  EmailUtil 4  time 5  os 6   7  Application(Frame): 8     email_util = 9     total_line= 010  11     __init__(self,master=None):12         ''''''13         super().__init__(master)   调用父类的初始化方法14         host = 15         port = 16         username = *********17         password = 18         self.email_util = EmailUtil(host=host,1)">19         self.email_util.login(username=username,1)">20         self.master = master21          self.pack(sIDe=top,fill=BOTH,expand=1)  # 此处填充父窗体22         self.create_Widget()23  24      create_Widget(self):25         self.img_logo = PhotoImage(file=logo.png26         self.btn_logo = button(image=self.img_logo,bg=#222E3C27         self.btn_logo.grID(row=0,column=0,sticky=N + E + W+S)28          收件箱初始化29         records = self.email_util.get_mail()30         for i  range(len(records)):31              时间特殊处理32             recv_date =  time.strftime(%Y-%m-%d",time.localtime(records[i][]))33             subject = {0}   {1}".format(recv_date,records[i][])34             (subject)35             num = records[i][36             btn_subject = button(self.master,text=subject,height=2,wIDth=30,bg=(#F0FFFF" if i%2==0 else #E6E6FA"),anchor=wlambda num=num: self.get_email_content(num) )37             btn_subject.grID(row=(i + 1),padx=2,pady=138          明细39         self.total_line=i40         self.web_vIEw = WebVIEw(self.master,wIDth=530,height=56041         self.web_vIEw.grID(row=0,column=1,rowspan=(i+2),pady=5,sticky=N + E + W)42  43     44         获取邮件明细45         content = self.email_util.get_email_content(num)46         47         if content.find(GBK')>0 or content.find(gbkcnblogs')>0:48             1-111149              content = content.encode().decode('gbk')50          print(content)51         self.save_data(content)52         abs_path =  os.path.abspath(content.HTML53         self.web_vIEw= WebVIEw(self.master,height=560,url=file://"+abs_path)54         self.web_vIEw.grID(row=0,rowspan=(self.total_line + 2),padx=5,1)">55  56  57      save_data(self,content):58         保存数据59         with open() as f:60             f.write(content)61  62  63 64     root = Tk()65     root.Title(个人邮箱66     root.geometry(760x580+200+20067     root.setvar(bgred68     app = Application(master=root)69     root.mainloop()
邮箱设置

如果要使用IMAP协议访问邮箱服务进行收发邮件,则必须进行邮箱设置,路径:登录邮箱-->设置-->账户-->POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务,如下所示:

 

 

 如果通过邮箱账户密码登录时,报如下错误,则表示需要通过授权码进行登录,如下所示:

 

 

 温馨提示:在第三方登录QQ邮箱,可能存在邮件泄露风险,甚至危害Apple ID安全,建议使用QQ邮箱手机版登录。

备注

逢雪宿芙蓉山主人

【作者】刘长卿【朝代】唐

日暮苍山远,天寒白屋贫。柴门闻犬吠,风雪夜归人。

 

总结

以上是内存溢出为你收集整理的Python通过IMAP实现邮箱客户端全部内容,希望文章能够帮你解决Python通过IMAP实现邮箱客户端所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1183738.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-02
下一篇 2022-06-02

发表评论

登录后才能评论

评论列表(0条)

保存