win32com + outlook 每次执行只捕获收件箱中 50% 的邮件?
win32com + outlook only capturing 50% of messages in inbox per execution?
我用 win32com 和 python3.x 创建了一个小代码,它只是通过 outlook 文件夹并对里面的邮件做一些事情(移动它们、阅读它们等)。
除了一个奇怪的小问题外,它运行完美...文件夹中仅处理了 50% 的项目!收件箱中有 500 件物品?分析了 250 个。 30? 15 留在收件箱中。 1?处理无问题。
如果我使用 "messages.Count",我可以看到邮箱中有多少封电子邮件 - 这个数字与我在 outlook 中看到的相符。无论如何,当看到一半的项目时,程序就结束了。该程序将倒计时 30、29、28...在 15 停止而不会抛出任何错误。
如果我稍微玩一下循环,执行 while messages:
,程序将倒数到 15,然后给我一个 "NoneType" 异常,向我表明 outlook 不是 "giving" 尽管邮箱中存在一些邮件,但仍有更多邮件发送至 python。
运行 在这两种情况下,程序将再次简单地处理剩余的 50% 的消息。
知道这里发生了什么吗?这是前景的事情吗?我什至不知道从哪里开始......这是代码的超级剥离版本。即使在这个级别,错误仍然存在。收件箱的 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()
主要问题是您在迭代 messages
的同时修改了它:
message.Move(subfolderO)
这并不明显,但这会修改 messages
。循环将缩小一个,但您的迭代器不会向后移动,因此您会错过容器中的下一个项目。
这是许多语言和容器实现中的常见问题。
所以不要这样做。
一种方法是复制容器并对其进行迭代,同时修改原始容器。
for message in list(messages):
...
message.Move(subfolderO)
另外,您不需要做:
message = messages.GetNext()
我遇到了完全相同的问题。迭代“.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()
迭代以使其仅移动第一项,并通过每次迭代修改原始消息 class。
我用 win32com 和 python3.x 创建了一个小代码,它只是通过 outlook 文件夹并对里面的邮件做一些事情(移动它们、阅读它们等)。
除了一个奇怪的小问题外,它运行完美...文件夹中仅处理了 50% 的项目!收件箱中有 500 件物品?分析了 250 个。 30? 15 留在收件箱中。 1?处理无问题。
如果我使用 "messages.Count",我可以看到邮箱中有多少封电子邮件 - 这个数字与我在 outlook 中看到的相符。无论如何,当看到一半的项目时,程序就结束了。该程序将倒计时 30、29、28...在 15 停止而不会抛出任何错误。
如果我稍微玩一下循环,执行 while messages:
,程序将倒数到 15,然后给我一个 "NoneType" 异常,向我表明 outlook 不是 "giving" 尽管邮箱中存在一些邮件,但仍有更多邮件发送至 python。
运行 在这两种情况下,程序将再次简单地处理剩余的 50% 的消息。
知道这里发生了什么吗?这是前景的事情吗?我什至不知道从哪里开始......这是代码的超级剥离版本。即使在这个级别,错误仍然存在。收件箱的 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()
主要问题是您在迭代 messages
的同时修改了它:
message.Move(subfolderO)
这并不明显,但这会修改 messages
。循环将缩小一个,但您的迭代器不会向后移动,因此您会错过容器中的下一个项目。
这是许多语言和容器实现中的常见问题。
所以不要这样做。
一种方法是复制容器并对其进行迭代,同时修改原始容器。
for message in list(messages):
...
message.Move(subfolderO)
另外,您不需要做:
message = messages.GetNext()
我遇到了完全相同的问题。迭代“.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()
迭代以使其仅移动第一项,并通过每次迭代修改原始消息 class。