You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 03:35:29