Python/Outlook:每次只收到一半的电子邮件



背景是我在Unix上有一个预定的工作,这个工作一夜之间给我发了数百封电子邮件。每天早上我都想保存这些电子邮件的附件。我编写了一个python代码片段,目的是实现流程自动化。然而,每次运行脚本时,似乎只有一半的电子邮件(在我的目标目录中(会得到处理。这就是我今天早上从日志中得到的:

2021-11-18 06:13:30,688 : INFO : utils.util : Before clean up. 335 items in total
2021-11-18 06:13:42,098 : INFO : utils.util : After clean up. 167 items remained
2021-11-18 06:14:17,968 : INFO : utils.util : Before clean up. 167 items in total
2021-11-18 06:14:25,660 : INFO : utils.util : After clean up. 83 items remained
2021-11-18 06:14:34,762 : INFO : utils.util : Before clean up. 83 items in total
2021-11-18 06:14:38,591 : INFO : utils.util : After clean up. 41 items remained
2021-11-18 06:14:47,633 : INFO : utils.util : Before clean up. 41 items in total
2021-11-18 06:14:49,745 : INFO : utils.util : After clean up. 20 items remained
2021-11-18 06:14:56,348 : INFO : utils.util : Before clean up. 20 items in total
2021-11-18 06:14:57,426 : INFO : utils.util : After clean up. 9 items remained
2021-11-18 06:15:15,807 : INFO : utils.util : Before clean up. 9 items in total
2021-11-18 06:15:16,260 : INFO : utils.util : After clean up. 4 items remained
2021-11-18 06:15:22,981 : INFO : utils.util : Before clean up. 4 items in total
2021-11-18 06:15:23,215 : INFO : utils.util : After clean up. 1 items remained
2021-11-18 06:15:36,117 : INFO : utils.util : Before clean up. 1 items in total
2021-11-18 06:15:36,164 : INFO : utils.util : After clean up. 0 items remained

335->167->83->41->20->9->4->1->0

关于潜在的问题是什么,你能给我一些提示吗?

这是我的代码:

import os
import win32com.client
def get_target_folder(folder: str):
outlook = win32com.client.Dispatch('outlook.application')
mapi = outlook.GetNamespace("MAPI")
target = mapi
dir = folder.split("\")
for d in dir:
try:
target = target.Folders(d)
except:
logger.error("Current folder path {}. The sub folder {} doesn't exist".format(target.FolderPath, d))
target = None
break
return target

def save_job_status():
mailfolder= config["OUTLOOK"]["JOBS"]
keyword = config["OUTLOOK"]["KEYWORD"]
destination = config["OUTLOOK"]["LOCALDATA"]
criteria = f"@SQL="urn:schemas:httpmail:subject" like '%{keyword}%'"
folder = get_target_folder(folder=mailfolder)
items = folder.items
emails = items.restrict(criteria)
logger.info("Before clean up. {} items in total".format(emails.count))
for email in emails:
try:
attachments = email.attachments
for attachment in attachments:
filename = attachment.FileName
attachment.SaveAsFile(os.path.join(destination, filename ))
email.Delete()
except:
logger.error("Can't operate on the email {}".format(email.Subject))
items = folder.items
logger.info("After clean up. {} items remained".format(items.count))

由于我还设置了outlook规则,所有邮件都会转到"outlook";JOBS";在我看来,文件夹是满足条件的,应该进行处理。我设置了一个";"标准";只是为了避免操作失误。

提前谢谢!

==============================确定的解决方案===================在参考@Dmitry Streblechenko的回答后,我理解了。这是一个集合,当我访问它时,我正在修改集合

为了解决这个问题,我所做的关键修改如下

count = emails.count
for i in range(count-1, -1, -1):
print("{} {}".format(i, emails[i].subject))
emails[i].Delete()

请注意,这是一种反向索引访问,即使用范围从最大到最小。当移除集合的底部时,仍然可以使用原始索引访问顶部的集合。

如果要修改集合(通过调用email.Delete()(,请不要使用for email in emails:循环。使用从emails.Count向下到1的下循环。

最新更新