002、163邮件附件批量下载
002、163邮件附件批量下载
问题描述:
近期收到n多邮件,含电子表格附件;现要求用Python批量下载邮件附件。
1 import tkinter as tk 2 import poplib 3 from email.parser import Parser 4 from email.header import decode_header 5 # from email.utils import parseaddr 6 import os 7 import time 8 import sys 9 10 11 # 单击“下载”按钮 12 def download(): 13 if en1.get() == "": 14 en1.insert(0, '请输入服务器地址!') 15 if en2.get() == "": 16 en2.insert(0, '请输入邮箱地址!') 17 if en3.get() == "": 18 en3.insert(0, '请输入身份认证密码!') 19 else: 20 # 链接到pop3服务器 21 # M = poplib.POP3("pop.163.com") 22 M = poplib.POP3(en1.get()) 23 # 认证:身份认证 24 # M.user("******@163.com") 25 M.user(en2.get()) 26 # M.pass_("****************") 27 M.pass_(en3.get()) 28 29 # 获取邮件数量 30 dd = len(M.list()[1]) 31 # print(M.list()[1]) 32 33 for i in range(1, dd + 1, 1): 34 # 获取最新一封邮件,注意索引号从1开始 35 resp, lines, octets = M.retr(i) 36 msg_content = b'\r\n'.join(lines).decode('utf-8') 37 # 解析邮件为Message对象 38 msg = Parser().parsestr(msg_content) 39 # 获取附件 40 f_list = get_att(msg, str(i)) 41 42 43 # 字符编码转换 44 def decode_str(s): 45 value, charset = decode_header(s)[0] 46 if charset: 47 value = value.decode(charset) 48 return value 49 50 51 def get_att(msg, id): 52 import email 53 attachment_files = [] 54 # 获取当前日期字符串 55 time_now = time.strftime("%Y%m%d", time.localtime()) 56 # 打印系统桌面路径 57 # print(os.path.join(os.path.expanduser("~"), 'Desktop')) 58 # 打印当前路径 59 # print(os.path.dirname(__file__)) 60 # 设置路径未系统桌面路径+'/'+当前日期,为存放下载文件路径 61 path = os.path.join(os.path.expanduser("~"), 'Desktop') + '/' + time_now 62 # 以path创建文件夹,如果文件夹存在则不创建 63 if not os.path.exists(path): 64 os.makedirs(path) 65 # print(f'文件夹 {path} 创建完成') 66 # INSERT表示在光标位置插入 67 t1.insert('end', f'文件夹 {path} 创建完成\n') 68 # t1.see(fm_main.END) 69 t1.update() 70 71 for part in msg.walk(): 72 # 获取附件名称类型 73 file_name = part.get_filename() 74 contType = part.get_content_type() 75 if file_name: 76 h = email.header.Header(file_name) 77 # 对附件名称进行解码 78 dh = email.header.decode_header(h) 79 filename = dh[0][0] 80 if dh[0][1]: 81 # 将附件名称可读化 82 filename = decode_str(str(filename, dh[0][1])) 83 # print(f'正在下载第{id}个附件 {filename}') 84 # INSERT表示在光标位置插入 85 t1.insert('end', f'正在下载第{id}个附件 {filename}\n') 86 t1.update() 87 # filename = filename.encode("utf-8") 88 # 下载附件 89 data = part.get_payload(decode=True) 90 91 path_one = path + "/" + f'第{id}个附件 ' + filename 92 # 在指定目录下创建文件,注意二进制文件需要用wb模式打开 93 att_file = open(path_one, 'wb') 94 attachment_files.append(filename) 95 # 保存附件 96 att_file.write(data) 97 # print( f'第{id}个附件 {filename}') 98 att_file.close() 99 100 return attachment_files 101 102 103 # 退出程序 104 def exit_sys(): 105 sys.exit() 106 107 108 if __name__ == '__main__': 109 fm_main = tk.Tk() 110 fm_main.title("邮件附件批量下载_v1.0") 111 fm_main.geometry('566x418') 112 113 fm_main.resizable(0, 0) # 设置窗口大小不可变 114 115 lb1 = tk.Label(fm_main, text="请输入邮件POP3服务器:").grid(row=0, column=0, sticky=tk.W) 116 # sticky=N + E + W,在水平、垂直方向上延伸,填满整个单元格 117 en1 = tk.Entry(fm_main, text='请输入POP3服务器地址') 118 en1.grid(row=0, column=1, sticky=tk.N + tk.E + tk.W) 119 lb2 = tk.Label(fm_main, text="请输入邮件地址:") 120 lb2.grid(row=1, column=0, sticky=tk.W) 121 en2 = tk.Entry(fm_main) 122 en2.grid(row=1, column=1, sticky=tk.N + tk.E + tk.W) 123 lb3 = tk.Label(fm_main, text="请输入身份认证密码:") 124 lb3.grid(row=2, column=0, sticky=tk.W) 125 en3 = tk.Entry(fm_main) 126 en3.grid(row=2, column=1, sticky=tk.N + tk.E + tk.W) 127 # columnspan=3,表示t1占用0,1二列 128 t1 = tk.Text(fm_main) 129 t1.grid(row=5, column=0, columnspan=2, sticky=tk.N + tk.E + tk.W) 130 131 b1 = tk.Button(fm_main, text='下载', command=download) 132 b1.grid(row=4, column=0, sticky=tk.N + tk.E + tk.W) 133 b2 = tk.Button(fm_main, text='退出', command=exit_sys) 134 b2.grid(row=4, column=1, sticky=tk.N + tk.E + tk.W) 135 136 en1.insert(0, 'pop.163.com') 137 en2.insert(0, '*********@163.com') 138 en3.insert(0, '************') 139 140 fm_main.mainloop()
程序效果如下:
小学生C++