如何从邮箱中批量下载距离当天最近一天的邮件附件.

电子邮件发送协议是一种基于“ 推 ”的协议,主要包括 SMTP ; 邮件接收协议则是一种基于“ 拉 ”的协议,主要包括 POP协议和 IMAP协议. "推"或者"拉"的时候,一个一个邮件就像排好队手拉手的小朋友,被发送出去或者接收回来.

本示例处理的是接收邮件的问题, 邮件都在远端的服务器上排着队,使用POP协议,是必须先把邮件都"拉"到本地,才能知道哪些邮件是你想要的,哪些是你不想要的. 但IMAP4协议可以预先读取邮件头,了解一些信息后,只下载你想获取的邮件,这样处理速度快,所以本示例及以后的示例问题,没特殊情况都使用IMAP协议. 

邮件附件的内容并不在文件头的信息里,只能通过先获取邮件附件的名字,从命名特征上看是不是你想获取的邮件.

本示例是下载每天从券商或期货商柜台发生到基金运营部门的数据专用邮箱的清算数据,目的是通过清算数据获得证券账户中的客户权益对基金产品的净值进行测算.

清算数据文件通常是一个单独的zip, rar扩展名的压缩包, 或者是txt和zip压缩包两个文件组合.

from imap_tools import MailBox  # 导入imap邮件处理模块
from datetime import date  # 导入日期处理模块
import os # 导入os模块,用于操作文件及文件夹

print("今天是:", date.today())
print("邮件附件文件夹初始化....")
# 定义清算文件打算存储的文件夹名称,由于本示例这个文件夹下只保存最近1日或者当日的邮件附件, 日期过了一天, 里面的数据就没用了,所以下载的附件会被删除. clearing_files_temp = "clearing_files_temp" dir_list = os.listdir()
if clearing_files_temp not in dir_list: os.mkdir(clearing_files_temp) print("存储附件的临时文件夹初始化完成") else: try: os.remove(clearing_files_temp+"\*.*") print("存储附件的临时文件夹初始化完成") except IOError: print("文件夹初始化失败,请手动删除{}文件夹后重试".format(clearing_files_temp))
print("开始登陆邮箱") date_flag = [] # 设置距离程序运行日期最近的,有清算邮件(相当于那天是清算日)的日期 with MailBox("你的imap服务器地址").login(" 你的账号", "你的密码或者授权码") as mailbox: require_num = 200 # 接收邮件的数量, 数据专用邮箱通常会有海量邮件,不指定会读取太多邮件 print("登陆成功,开始接收带附件的最近{}邮件".format(require_num)) i = 1 for msg in mailbox.fetch(limit=require_num, reverse=True): # 为了避免读取全部的邮件,加上了limit的匹配参数,读取200封邮件 for att in msg.attachments: # msg为上一行取得的全部邮件,attachments带有邮件的附件各种特征值 if att.filename: # 如果附件的文件名不为空 # 如果扩展名为zip,txt,rar等清算文件常用扩展名 if att.filename.endswith(".zip") or att.filename.endswith(".txt") or att.filename.endswith(".rar"): if date_flag == []: # 只有最近清算日内容为空的时候,才添加日期,这样会得到距离程序运行日期最近的清算日的日期 date_flag=(str(msg.date).split(" ")) print("最近的清算日期",date_flag[0]) if date_flag[0] in str(msg.date): # 如果最近清算日与邮件日期相同,保存邮件附件,确保被保存的附件是最新的 att_data = att.payload # 获得附件的内容 print("邮件标题:", i,msg.subject, "邮件时间:", msg.date, "发件人", msg.from_, "附件", att.filename) f = open(clearing_files_temp+"/"+att.filename, 'wb') # 用二进制打开,一般邮件附件都是二进制的. f.write(att_data) f.close() i = i + 1 if i == require_num: print("读取的邮件数量可能不足,为避免有当日的清算文件没有读取到,请增加接收邮件的数量") else: print("邮件附件下载成功,已保存到临时文件夹待进一步处理")

  

posted @ 2022-01-24 01:54  歪理斜说  阅读(596)  评论(0编辑  收藏  举报