win32com + Outlook 每次执行仅捕获收件箱中 50% 的邮件

问题描述 投票:0回答:2

我用 win32com 和 Python 3.x 创建了一个小代码,它简单地通过一个 Outlook 文件夹并对里面的消息做一些事情(移动它们,阅读它们等)。

它工作完美,除了一个奇怪的小问题......文件夹中只有 50% 的项目正在处理!收件箱中有 500 件物品?分析了 250 个。 30? 15 留在收件箱中。 1?处理无问题。

如果我使用“messages.Count”,我可以看到邮箱中有多少封电子邮件——这个数字与我在 outlook 中看到的相符。无论如何,当看到一半的项目时,程序就结束了。该程序将倒数 30、29、28...在 15 处停止而不会抛出任何错误。

如果我稍微玩一下循环,做

while messages:
,程序将倒数到 15,然后给我一个“NoneType”异常,向我表明 outlook 不再向 python“提供”任何消息,尽管有一些存在于邮箱中。

在这两种情况下再次运行程序将只处理剩余的 50% 的消息。

这里发生了什么?这是 Outlook 的问题吗?我什至不知道从哪里开始......这是代码的超级剥离版本。即使在这个级别,错误仍然存在。收件箱的 50% 被移动,50% 保留。在剩下的 50% 中,有一半在下次执行时处理。

    import win32com.client

    outlook = win32com.client.Dispatch("Outlook.Application")
    namespace = outlook.GetNamespace("MAPI")
    root_folder = namespace.Folders.Item(1) # Choose account
    subfolder = root_folder.Folders['Inbox'] # Choose folder, subfolder
    subfolderO = root_folder.Folders['Inbox'].Folders['Closed'] # Choose folder, subfolder
    messages = subfolder.Items
    message = messages.GetFirst()

    for message in messages:
        print("\n", message.Sender, "\n", message.To, "\n ", message.Subject',"\n", message.CreationTime, "\n_________")
        message.Move(subfolderO)
        message = messages.GetNext()
python python-3.x outlook automation win32com
2个回答
4
投票

主要问题是您在迭代它的同时修改了

messages

message.Move(subfolderO)

不明显,但这会修改

messages
。循环将缩小一个,但您的迭代器不会向后移动,因此您会错过容器中的下一个项目。

这是很多语言和容器实现的通病。

所以不要这样做。

一种方法是复制容器并对其进行迭代,同时修改原始容器。

for message in list(messages):
    ...
    message.Move(subfolderO)

另外,你不需要做:

    message = messages.GetNext()

0
投票

我遇到了完全相同的问题。迭代“.Move”只能通过一半的邮件项目。 Peter Wood解释有所帮助,尽管花了一段时间才弄清楚这个问题。:)我相信下面修改后的代码会起作用:

import win32com.client

outlook = win32com.client.Dispatch("Outlook.Application")
namespace = outlook.GetNamespace("MAPI")
root_folder = namespace.Folders.Item(1) #choose account
subfolder = root_folder.Folders['Inbox'] #choose folder, subfolder
subfolderO = root_folder.Folders['Inbox'].Folders['Closed'] #choose                                                folder, subfolder
messages = subfolder.Items
message = messages.GetFirst()

for message in list(messages):
    print("\n", message.Sender,"\n", message.To, "\n ", message.Subject',"\n", message.CreationTime, "\n_________")
    message.Move(subfolderO)
    messages = subfolder.Items
    message = messages.GetFirst()

迭代使得它只移动第一个项目,并通过每次迭代修改原始消息类。

© www.soinside.com 2019 - 2024. All rights reserved.