如何用Python脚本按日期范围筛选Outlook邮件并下载符合条件的附件?
Outlook邮件自动化:按日期范围筛选并下载指定主题邮件的附件
嘿,我来帮你把这个Python脚本补全,实现按日期范围筛选+指定主题+下载附件的完整功能!结合你已有的代码,我会优化逻辑并添加你需要的日期筛选功能,同时让脚本更健壮。
核心思路拆解
- 用Outlook的
Restrict方法做日期范围筛选,比遍历所有邮件效率高太多(尤其是收件箱邮件多的时候) - 保留指定主题的判断,支持精确/模糊匹配
- 自动检查邮件是否带附件,避免无效操作
- 自动创建附件保存文件夹,还能给文件名加时间戳防止重复
完整可运行代码
import win32com.client import os from datetime import datetime, timedelta # ---------------------- 自定义配置区 ---------------------- TARGET_SUBJECT = "TEST MAIL" # 你要筛选的邮件主题,支持模糊匹配 DOWNLOAD_FOLDER = os.path.join(os.getcwd(), "Outlook_Attachments") # 附件保存路径 DATE_RANGE_DAYS = 7 # 筛选最近7天的邮件,按需修改成你需要的天数 # --------------------------------------------------------- # 创建附件保存文件夹(不存在则自动创建) if not os.path.exists(DOWNLOAD_FOLDER): os.makedirs(DOWNLOAD_FOLDER) # 连接到Outlook客户端 outlook = win32com.client.Dispatch("Outlook.Application").GetNameSpace("MAPI") inbox = outlook.GetDefaultFolder(6) # 6代表默认收件箱,其他文件夹编号:3=已发送,4=草稿,5=已删除 messages = inbox.Items # 优化筛选效率:按接收时间倒序排序,启用 recurrence 支持 messages.Sort("[ReceivedTime]", True) messages.IncludeRecurrences = True # 构建日期筛选条件:Outlook要求日期格式为"yyyy-mm-dd hh:mm:ss" start_date = datetime.now() - timedelta(days=DATE_RANGE_DAYS) filter_criteria = f"[ReceivedTime] >= '{start_date.strftime('%Y-%m-%d %H:%M:%S')}'" filtered_messages = messages.Restrict(filter_criteria) print(f"正在扫描最近{DATE_RANGE_DAYS}天内主题包含「{TARGET_SUBJECT}」的邮件...") for msg in filtered_messages: # 主题匹配:用in是模糊匹配,改成==就是精确匹配 if TARGET_SUBJECT in msg.Subject: # 检查邮件是否有附件 if msg.Attachments.Count > 0: print(f"\n找到符合条件的邮件:【{msg.Subject}】,开始下载附件") for att in msg.Attachments: # 添加时间戳避免文件名重复 timestamp = datetime.now().strftime('%Y%m%d_%H%M%S') save_filename = f"{timestamp}_{att.FileName}" save_path = os.path.join(DOWNLOAD_FOLDER, save_filename) att.SaveAsFile(save_path) print(f"附件已保存:{save_path}") else: print(f"\n邮件【{msg.Subject}】符合主题条件,但未包含附件") print("\n所有筛选和下载操作完成!")
关键细节说明
- 日期筛选优化:
Restrict方法是Outlook内置的筛选机制,比手动遍历所有邮件快很多,适合大数据量场景 - 主题匹配灵活度:如果需要精确匹配主题,把
TARGET_SUBJECT in msg.Subject改成msg.Subject == TARGET_SUBJECT即可 - 重复文件处理:给附件文件名添加了时间戳,避免同文件名附件被覆盖
- 文件夹编号:如果需要操作其他文件夹,替换
GetDefaultFolder(6)里的数字就行,常用编号我已经在注释里标注了
内容的提问来源于stack exchange,提问作者Carl




