如何用Python提取嵌套邮件中的XLS附件?附Outlook代码排查
解决方法
1. 强制同步Exchange收件箱
Outlook缓存模式下,超出本地缓存期限的邮件仅存储在Exchange服务器,需先触发同步才能让本地客户端获取到这些邮件。可通过SyncObjects实现自动同步:
# 获取收件箱后添加同步逻辑 sync_objects = mapi.SyncObjects sync_object = sync_objects.Item(1) # 通常第一个为收件箱同步对象 sync_object.Start() # 根据网络情况设置等待时间,确保同步完成 import time time.sleep(10)
2. 修正Restrict查询的语法问题
原代码存在两处关键错误:
- Subject查询未用引号包裹,若包含特殊字符会导致语法失效
- 日期格式需匹配Outlook要求的格式(
yyyy-mm-dd hh:mm:ss更可靠)
修正后的查询逻辑:
# 重构日期格式 received_dt = datetime.now() - BDay(600) date_str = received_dt.strftime('%Y-%m-%d') Subject = f'OPÇÕES RV - {received_dt.strftime("%d/%m/%Y")}' # 合并时间范围与主题查询,减少多次Restrict调用 start_time = f"{date_str} 13:00:00" end_time = f"{date_str} 23:59:59" messages = messages.Restrict(f"[ReceivedTime] >= '{start_time}' AND [ReceivedTime] <= '{end_time}' AND [Subject] = '{Subject}'")
3. 递归遍历收件箱子文件夹(可选)
若邮件被误移至收件箱子文件夹,可通过递归遍历查找目标邮件:
def search_folder(folder, subject_filter): found_messages = [] try: items = folder.Items.Restrict(f"[Subject] = '{subject_filter}'") found_messages.extend(list(items)) # 递归遍历所有子文件夹 for subfolder in folder.Folders: found_messages.extend(search_folder(subfolder, subject_filter)) except Exception as e: print(f"访问文件夹 {folder.Name} 出错: {str(e)}") return found_messages # 使用方式 all_found = search_folder(inbox, Subject)
完整修正代码
import os import time from datetime import datetime from dateutil.parser import parse from dateutil.relativedelta import relativedelta from pathlib import Path import win32com.client path = 'C:/Users/moliveira/Desktop/projeto_email' os.chdir(path) output_dir = Path.cwd() output_dir.mkdir(parents=True, exist_ok=True) outlook = win32com.client.Dispatch("Outlook.Application") mapi = outlook.GetNamespace("MAPI") # 强制同步收件箱 sync_objects = mapi.SyncObjects sync_object = sync_objects.Item(1) sync_object.Start() time.sleep(10) inbox = mapi.GetDefaultFolder(6) messages = inbox.Items # 计算日期与构建主题 received_dt = datetime.now() - relativedelta(days=600) date_aux = received_dt subject_date = received_dt.strftime('%d/%m/%Y') Subject = f'OPÇÕES RV - {subject_date}' # 构建Outlook兼容的时间查询条件 date_str = received_dt.strftime('%Y-%m-%d') start_time = f"{date_str} 13:00:00" end_time = f"{date_str} 23:59:59" # 合并查询条件 messages = messages.Restrict(f"[ReceivedTime] >= '{start_time}' AND [ReceivedTime] <= '{end_time}' AND [Subject] = '{Subject}'") try: message_list = list(messages) if not message_list: print("未找到匹配邮件,开始遍历所有子文件夹...") # 调用递归搜索函数 def search_folder(folder, subject_filter): found = [] try: items = folder.Items.Restrict(f"[Subject] = '{subject_filter}'") found.extend(list(items)) for subfolder in folder.Folders: found.extend(search_folder(subfolder, subject_filter)) except Exception as e: print(f"访问文件夹 {folder.Name} 出错: {str(e)}") return found message_list = search_folder(inbox, Subject) for message in message_list: try: sender = message.SenderName if message.Sender else "未知发件人" for attachment in message.Attachments: save_path = os.path.join(output_dir, attachment.FileName) attachment.SaveAsFile(save_path) print(f"已保存附件: {attachment.FileName} 来自 {sender}") except Exception as e: print(f"保存附件出错: {str(e)}") except Exception as e: print(f"处理邮件出错: {str(e)}") date = date_aux.strftime('%d_%m_%Y')
内容的提问来源于stack exchange,提问作者TannishSphinx
相关产品推荐
相关产品推荐

