使用Imbox遍历多封邮件提取附件并存储到不同路径的问题
错误原因
- 循环逻辑错误:你采用了路径遍历嵌套邮件遍历的双重循环结构,会导致每一个路径下都会写入所有符合条件的邮件附件,最终每个路径下的文件都会被最后一封邮件的附件覆盖
- Imbox的
messages()方法返回的是生成器对象,第一次遍历完成后内容就被完全消费,后续遍历无法再读取到邮件内容
修复代码
import traceback path_list = ['c:/Users/../Trades1/', 'c:/Users/../Trades2/'] mail = Imbox(host, username=username, password=password, ssl=True, ssl_context=None, starttls=False) # 先将生成器转为列表,保存所有匹配的邮件,避免遍历一次就失效 messages = list(mail.messages(folder='Inbox', subject='Your requested Daily-trade report is attached')) # 用zip将路径和邮件一一绑定,实现第1封邮件存第1个路径,第2封存第2个路径的需求 for save_path, (uid, message) in zip(path_list, messages): mail.mark_seen(uid) for attachment in message.attachments: try: att_fn = attachment.get('filename') # 可选:增加文件名校验,只存储目标命名的zip附件,避免误存其他附件 if att_fn == 'report_10_november.zip': download_path = f"{save_path}Trades.zip" with open(download_path, "wb") as fp: fp.write(attachment.get('content').read()) except: print(traceback.format_exc())
逻辑说明
- 把生成器转成列表后,所有匹配的邮件都会被持久化保存在变量中,不会出现遍历一次就读不到的问题
zip()方法会按顺序把路径列表和邮件列表的元素配对,刚好匹配你需要的邮件和存储路径一一对应的需求,不需要嵌套循环,不会出现覆盖问题- 可选的文件名校验逻辑可以过滤掉邮件内的其他无关附件,提升代码稳定性
内容的提问来源于stack exchange,提问作者Rodrigo
相关产品推荐
相关产品推荐

