简单介绍Python实现邮件自动下载的示例

 2471

本篇文章给大家带来了关于Python的相关知识,详细介绍了如何利用Python语言实现邮件自动下载以及附件解析功能,文中的示例代码讲解详细,感下面一起来看一下,希望对大家有帮助。


简单介绍Python实现邮件自动下载的示例


开始码代码之前,我们先来了解一下三种邮件服务协议:

1、SMTP协议

SMTP(Simple Mail Transfer Protocol),即简单邮件传输协议。相当于中转站,将邮件发送到客户端。

2、POP3协议

POP3(Post Office Protocol 3),即邮局协议的第3个版本,是电子邮件的第一个离线协议标准。该协议把邮件下载到本地计算机,不与服务器同步,缺点是更易丢失邮件或多次下载相同的邮件。

3、IMAP协议

IMAP(Internet Mail Access Protocol),即交互式邮件存取协议。该协议连接远程邮箱直接操作,与服务器内容同步。

然后介绍一下email包

这个包的中心组件是代表电子邮件消息的“对象模型”。 应用程序主要通过在 message 子模块中定义的对象模型接口与这个包进行交互。 应用程序可以使用此 API 来询问有关现有电子邮件的问题、构造新的电子邮件,或者添加或移除自身也使用相同对象模型接口的电子邮件子组件。 也就是说,遵循电子邮件消息及其 MIME 子组件的性质,电子邮件对象模型是所有提供 EmailMessage API 的对象所构成的树状结构。

接下来我们通过具体的代码实现一个登录邮箱客户端,下载邮件,解析邮件附件内容的功能。

首先我们需要定义一个邮件解析的类,该类需要三个变量:

1、邮箱所属的imap服务地址;

2、邮箱账号;

3、邮箱密码【注:不同邮箱需要不同的安全策略,例如qq邮箱需要短信验证,获取登录授权码,而不是明文密码去登录远程客户端】

  1. class Email_parse:
  2.  
  3.     def __init__(self,remote_server_url,email_url,password):
  4.         # imap服务地址
  5.         self.remote_server_url = remote_server_url
  6.         # 邮箱账号
  7.         self.email_url = email_url
  8.         # 邮箱密码
  9.        self.password = password

然后定义类中入口函数,登录远程,默认获取第一页所有的邮件。我们获取邮件的主题,并打印出来【不同邮件主题的编码可能不同,二进制需要转码才能正确显示】

  1. def main_parse_Email(self):
  2.     """入口函数,登录imap服务"""
  3.     server = imaplib.IMAP4_SSL(self.remote_server_url, 993)
  4.     server.login(self.email_url, self.password)
  5.     server.select('INBOX')
  6.     status,data = server.search(None,"ALL")
  7.     if status != 'OK':
  8.         raise Exception('read email error')
  9.     emailids = data[0].split()
  10.     mail_counts = len(emailids)
  11.     print("count:",mail_counts)
  12.     # 邮件的遍历是按时间从后往前,这里我们选择最新的一封邮件
  13.     for i in range(mail_counts - 1, mail_counts - 2, -1):
  14.         status, edata = server.fetch(emailids[i], '(RFC822)')
  15.         msg = email.message_from_bytes(edata[0][1])
  16.         #获取邮件主题title
  17.         subject = email.header.decode_header(msg.get('subject'))
  18.         if type(subject[-1][0]) == bytes:
  19.             title = subject[-1][0].decode(str(subject[-1][1]))
  20.         elif type(subject[-1][0]) == str:
  21.             title = subject[-1][0]
  22.         print("title:", title)

其中,msg变量保存的就是邮件的主体,接下来因为会重复用到msg和tilte,我们将构造一个类函数返回msg和title。

  1. def get_email_title(msg):
  2.     subject = email.header.decode_header(msg.get('subject'))
  3.     if type(subject[-1][0]) == bytes:
  4.         title = subject[-1][0].decode(str(subject[-1][1]))
  5.     elif type(subject[-1][0]) == str:
  6.         title = subject[-1][0]
  7.     print("title:", title)
  8.     return title

解析邮件,我们分为两部分,邮件正文【HTML】和附件【xlsx等】,判断有附件,我们就保存到固定的路径下。表格的解析不再赘述了,pandas之类的包足以搞定。

  1. def get_att(msg):
  2.     """获取附件并下载"""
  3.     filename = Email_parse.get_email_name(msg)
  4.     for part in msg.walk():
  5.         file_name = part.get_param("name")
  6.         if file_name:
  7.             data = part.get_payload(decode=True)
  8.             if data != None:
  9.                 att_file = open('./src/' + filename, 'wb')
  10.                 att_file.write(data)
  11.                 att_file.close()
  12.             else:
  13.                 pass

邮件正文内容,我们直接解析html,将文本内容直接保存到.txt文件中,方便读取。

  1. def get_text_from_HTML(msg):
  2.     """获取邮件中的html"""
  3.     filename = Email_parse.get_email_name(msg)
  4.     current_title = Email_parse.get_email_title(msg)
  5.     print("filename:",filename,type(filename))
  6.     for part in msg.walk():
  7.         if not part.is_multipart():
  8.             result = part.get_payload(decode=True)
  9.             result = result.decode('gbk')
  10.             f = open(f'./src/{current_title}.txt','w')
  11.             f.write(result)
  12.             f.close()
  13.             return result

完整代码如下:

  1. import email
  2. import imaplib
  3. from email.header import decode_header
  4. import pandas as pd
  5. import datetime
  6.  
  7.  
  8. class Email_parse:
  9.     def __init__(self,remote_server_url,email_url,password):
  10.         self.remote_server_url = remote_server_url
  11.         self.email_url = email_url
  12.         self.password = password
  13.  
  14.     def get_att(msg):
  15.         filename = Email_parse.get_email_name(msg)
  16.         for part in msg.walk():
  17.             file_name = part.get_param("name")
  18.             if file_name:
  19.                 data = part.get_payload(decode=True)
  20.                 if data != None:
  21.                     att_file = open('./src/' + filename, 'wb')
  22.                     att_file.write(data)
  23.                     att_file.close()
  24.                 else:
  25.                     pass
  26.  
  27.     def get_email_title(msg):
  28.         subject = email.header.decode_header(msg.get('subject'))
  29.         if type(subject[-1][0]) == bytes:
  30.             title = subject[-1][0].decode(str(subject[-1][1]))
  31.         elif type(subject[-1][0]) == str:
  32.             title = subject[-1][0]
  33.         print("title:", title)
  34.         return title
  35.  
  36.  
  37.     def get_email_name(msg):
  38.         for part in msg.walk():
  39.             file_name = part.get_param("name")
  40.             if file_name:
  41.                 h = email.header.Header(file_name)
  42.                 dh = email.header.decode_header(h)
  43.                 filename = dh[0][0]
  44.                 if dh[0][1]:
  45.                     value, charset = decode_header(str(filename, dh[0][1]))[0]
  46.                     if charset:
  47.                         filename = value.decode(charset)
  48.                         print("附件名称:", filename)
  49.                         return filename
  50.  
  51.  
  52.     def main_parse_Email(self):
  53.         server = imaplib.IMAP4_SSL(self.remote_server_url, 993)
  54.         server.login(self.email_url, self.password)
  55.         server.select('INBOX')
  56.         status,data = server.search(None,"ALL")
  57.         if status != 'OK':
  58.             raise Exception('read email error')
  59.         emailids = data[0].split()
  60.         mail_counts = len(emailids)
  61.         print("count:",mail_counts)
  62.         for i in range(mail_counts - 1, mail_counts - 2, -1):
  63.             status, edata = server.fetch(emailids[i], '(RFC822)')
  64.             msg = email.message_from_bytes(edata[0][1])
  65.             subject = email.header.decode_header(msg.get('subject'))
  66.             if type(subject[-1][0]) == bytes:
  67.                 title = subject[-1][0].decode(str(subject[-1][1]))
  68.             elif type(subject[-1][0]) == str:
  69.                 title = subject[-1][0]
  70.             print("title:", title)
  71.             Email_parse.get_att(msg)
  72.             Email_parse.get_text_from_HTML(msg)
  73.  
  74.  
  75.     def get_text_from_HTML(msg):
  76.         filename = Email_parse.get_email_name(msg)
  77.         current_title = Email_parse.get_email_title(msg)
  78.         print("filename:",filename,type(filename))
  79.         for part in msg.walk():
  80.             if not part.is_multipart():
  81.                 result = part.get_payload(decode=True)
  82.                 result = result.decode('gbk')
  83.                 f = open(f'./src/{current_title}.txt','w')
  84.                 f.write(result)
  85.                 f.close()
  86.                 return result
  87.  
  88. if __name__ == "__main__":
  89.     remote_server_url = 'imap.qq.com'
  90.     email_url = "*********@qq.com"
  91.     password = "**********"
  92.     demo = Email_parse(remote_server_url,email_url,password)
  93.     demo.main_parse_Email()

运行结果:


简单介绍Python实现邮件自动下载的示例

简单介绍Python实现邮件自动下载的示例

本文网址:https://www.zztuku.com/detail-12976.html
站长图库 - 简单介绍Python实现邮件自动下载的示例
申明:本文转载于《脚本之家》,如有侵犯,请 联系我们 删除。

评论(0)条

您还没有登录,请 登录 后发表评论!

提示:请勿发布广告垃圾评论,否则封号处理!!

    编辑推荐

    jQ拖拽360度旋转
    Laravel怎么实现Ajax分页