python-3.x win32com + Outlook每次执行仅捕获收件箱中50%的邮件

3htmauhk  于 2023-03-20  发布在  Python
关注(0)|答案(2)|浏览(705)

我用win32 com和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()
nwo49xxi

nwo49xxi1#

主要的问题是,在对messages进行迭代时,您需要对其进行修改:

message.Move(subfolderO)

这并不明显,但这将修改messages,循环将缩小一个,但迭代器不会向后移动,因此会错过容器中的下一项。
这是许多语言和容器实现中的常见问题。
那就别做了。
一种方法是创建容器的副本,然后迭代该副本,同时修改原始容器。

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

此外,您不需要执行以下操作:

message = messages.GetNext()
eanckbw9

eanckbw92#

我也遇到过同样的问题。迭代.“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()

迭代以使其只移动第一个项,并在每次迭代中修改原始的messages类。

相关问题