python win32com:删除 Outlook 中的多封电子邮件
python win32com: Delete multiple emails in Outlook
我需要通过 win32com 模块从 python 中删除 Outlook 中的多封电子邮件。
我知道有一个 VBA 方法 MailItem.Delete() 可通过 COM 用于 win32com 并且它有效;但是删除多于一封电子邮件时非常非常慢,因为必须按顺序删除电子邮件,即循环遍历 MailItem 电子邮件集合。
有没有什么方法可以一次删除选定的邮件项目集合,比如 MailItemCollection.DeleteAll()?
此外,如果以上不可能;是否有可能通过多线程方法删除许多电子邮件,即将 mailItems 的集合分成 4 个子集;有 4 个线程在上面运行吗?
我想因为我可以通过它的 GUI 非常快速地删除 outlook 中的多封电子邮件,所以必须有一种方法可以让我通过 COM 做同样的事情 API。
不在 OOM 中 - MailItem.Delete
或 Items.Remove(Index)
就是你得到的。
在扩展 MAPI 级别(C++ 或 Delphi,但不是 Python),您可以使用 IMAPIFolder.DeleteMessages (which takes a list of entry ids). Or you can use IMAPIFolder.EmptyFolder 删除多封邮件(删除文件夹中的所有邮件)。
如果使用 Redemption (any language; I am its author) is an option, you can use RDOFolder2.EmptyFolder
or RDOFolder.Items.RemoveMultiple
. RDOFolder
can be retrieved from RDOSession。GetRDOObjectFromOutlookObject
如果您将 Outlook 的 MAPIFolder
对象作为参数传递。
除了@Dimitry 的精彩回答之外,我将添加一条可能对您很重要的评论:如果您在迭代项目时开始从项目中删除,可能会发生奇怪的事情。
例如在我的系统上有以下 Python 代码:
for mail in folder.Items:
mail.Delete()
以及
for index, mail in enumerate(folder.Items, 1):
folder.Remove(index)
两者都只删除了 folder
中的一半项目!原因似乎是 Items 在内部使用一系列索引来提供迭代器,因此每次删除一个元素时,列表的尾部都会移动一个...
要删除文件夹中的所有项目,请尝试:
for i in range(len(folder.Items)):
folder.Remove(1)
如果您需要按特定条件进行筛选,请考虑先收集 EntryID,然后删除搜索 ID:
ids = []
for i in range(len(folder.Items), 1):
if to_be_deleted(folder.Items[index]):
ids.append(index)
for id in ids:
outlook.GetEntryByID(id).Delete()
不过,我想它的性能会更差 :c
上面的 Dedalus 回答得很好。想做一个更简洁的代码版本:
import win32com.client
outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
# Select main Inbox
inbox = outlook.GetDefaultFolder(6)
messages = inbox.Items
# Delete all messages from a specific sender
sender = 'myname@abc.com'
try:
for message in messages:
try:
s = message.sender
s = str(s)
if s == sender:
message.Delete()
except:
pass
except:
pass
您可能不需要两个 "trys",但我发现将脚本应用到长时间且频繁使用的收件箱时它会更稳定。通常我将它与一个脚本结合使用,该脚本将消息 = inbox.Items 限制在一周内,因此它不会处理整个收件箱。
我错过了什么吗? Application 和 NameSpace 对象似乎都没有 GetEntryByID 方法,尽管 Dedalus 指出的其余部分是正确的。
命名空间对象有一个 GetItemFromID 方法,而 MailItem 对象有一个 EntryID 属性,只要它们不被重新组织到不同的文件夹中,它将唯一地标识它们。
我的全解:
import win32com.client
outlook = win32com.client.gencache.EnsureDispatch("Outlook.Application")
folders = outlook.GetNamespace("MAPI")
inbox= folders.GetDefaultFolder(6)
messages=inbox.Items
email_ids = []
folder_id = inbox.StoreID
# Here create a function to isolate/exclude. Below is just an example of filtering by a subject line.
email_subjects = ['Subj1','Subj2','Subj3']
for i in range(len(messages)):
if any(header in inbox.Items[i].Subject for header in email_subjects):
email_ids.append(inbox.Items[i].EntryID)
for id in email_ids:
folders.GetItemFromID(id, folder_id).Delete()
对我来说,它通过反向迭代项目来工作。
旧:
for mail in folder.Items:
if 'whatever' in mail.Subject: # just a condition (optional)
mail.Delete()
新密码:
for mail in reversed(folder.Items): # just tried deleting Items in reverse order
if 'whatever' in mail.Subject: # just a condition (optional)
mail.Delete()
希望这对某人有所帮助。
我已经在本地 Outlook 中实施了替代解决方案,通过直接使用 VBA 代码或 Outlook 过滤器规则将电子邮件项目 from.inbox 文件夹移动到已删除项目文件夹或存档文件夹。
这样,我只需每周一次手动清空已删除的项目文件夹(当然这个周期性步骤也可以编程)。
我观察到这种策略可以更有效,而不是使用代码删除每个项目的项目(你提到了 internal.indexes 问题)。
我需要通过 win32com 模块从 python 中删除 Outlook 中的多封电子邮件。
我知道有一个 VBA 方法 MailItem.Delete() 可通过 COM 用于 win32com 并且它有效;但是删除多于一封电子邮件时非常非常慢,因为必须按顺序删除电子邮件,即循环遍历 MailItem 电子邮件集合。
有没有什么方法可以一次删除选定的邮件项目集合,比如 MailItemCollection.DeleteAll()?
此外,如果以上不可能;是否有可能通过多线程方法删除许多电子邮件,即将 mailItems 的集合分成 4 个子集;有 4 个线程在上面运行吗?
我想因为我可以通过它的 GUI 非常快速地删除 outlook 中的多封电子邮件,所以必须有一种方法可以让我通过 COM 做同样的事情 API。
不在 OOM 中 - MailItem.Delete
或 Items.Remove(Index)
就是你得到的。
在扩展 MAPI 级别(C++ 或 Delphi,但不是 Python),您可以使用 IMAPIFolder.DeleteMessages (which takes a list of entry ids). Or you can use IMAPIFolder.EmptyFolder 删除多封邮件(删除文件夹中的所有邮件)。
如果使用 Redemption (any language; I am its author) is an option, you can use RDOFolder2.EmptyFolder
or RDOFolder.Items.RemoveMultiple
. RDOFolder
can be retrieved from RDOSession。GetRDOObjectFromOutlookObject
如果您将 Outlook 的 MAPIFolder
对象作为参数传递。
除了@Dimitry 的精彩回答之外,我将添加一条可能对您很重要的评论:如果您在迭代项目时开始从项目中删除,可能会发生奇怪的事情。 例如在我的系统上有以下 Python 代码:
for mail in folder.Items:
mail.Delete()
以及
for index, mail in enumerate(folder.Items, 1):
folder.Remove(index)
两者都只删除了 folder
中的一半项目!原因似乎是 Items 在内部使用一系列索引来提供迭代器,因此每次删除一个元素时,列表的尾部都会移动一个...
要删除文件夹中的所有项目,请尝试:
for i in range(len(folder.Items)):
folder.Remove(1)
如果您需要按特定条件进行筛选,请考虑先收集 EntryID,然后删除搜索 ID:
ids = []
for i in range(len(folder.Items), 1):
if to_be_deleted(folder.Items[index]):
ids.append(index)
for id in ids:
outlook.GetEntryByID(id).Delete()
不过,我想它的性能会更差 :c
上面的 Dedalus 回答得很好。想做一个更简洁的代码版本:
import win32com.client
outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
# Select main Inbox
inbox = outlook.GetDefaultFolder(6)
messages = inbox.Items
# Delete all messages from a specific sender
sender = 'myname@abc.com'
try:
for message in messages:
try:
s = message.sender
s = str(s)
if s == sender:
message.Delete()
except:
pass
except:
pass
您可能不需要两个 "trys",但我发现将脚本应用到长时间且频繁使用的收件箱时它会更稳定。通常我将它与一个脚本结合使用,该脚本将消息 = inbox.Items 限制在一周内,因此它不会处理整个收件箱。
我错过了什么吗? Application 和 NameSpace 对象似乎都没有 GetEntryByID 方法,尽管 Dedalus 指出的其余部分是正确的。
命名空间对象有一个 GetItemFromID 方法,而 MailItem 对象有一个 EntryID 属性,只要它们不被重新组织到不同的文件夹中,它将唯一地标识它们。
我的全解:
import win32com.client
outlook = win32com.client.gencache.EnsureDispatch("Outlook.Application")
folders = outlook.GetNamespace("MAPI")
inbox= folders.GetDefaultFolder(6)
messages=inbox.Items
email_ids = []
folder_id = inbox.StoreID
# Here create a function to isolate/exclude. Below is just an example of filtering by a subject line.
email_subjects = ['Subj1','Subj2','Subj3']
for i in range(len(messages)):
if any(header in inbox.Items[i].Subject for header in email_subjects):
email_ids.append(inbox.Items[i].EntryID)
for id in email_ids:
folders.GetItemFromID(id, folder_id).Delete()
对我来说,它通过反向迭代项目来工作。
旧:
for mail in folder.Items:
if 'whatever' in mail.Subject: # just a condition (optional)
mail.Delete()
新密码:
for mail in reversed(folder.Items): # just tried deleting Items in reverse order
if 'whatever' in mail.Subject: # just a condition (optional)
mail.Delete()
希望这对某人有所帮助。
我已经在本地 Outlook 中实施了替代解决方案,通过直接使用 VBA 代码或 Outlook 过滤器规则将电子邮件项目 from.inbox 文件夹移动到已删除项目文件夹或存档文件夹。 这样,我只需每周一次手动清空已删除的项目文件夹(当然这个周期性步骤也可以编程)。 我观察到这种策略可以更有效,而不是使用代码删除每个项目的项目(你提到了 internal.indexes 问题)。