我需要通过win32com模块从python中删除Outlook中的多封电子邮件。
我知道有一个VBA方法MailItem.Delete()可通过COM用于win32com,并且可以工作;但是删除多个电子邮件时非常慢,因为必须依次删除电子邮件,即遍历电子邮件的MailItem集合。
是否可以立即删除选定的mailItem集合,例如MailItemCollection.DeleteAll()?
此外,如果不可能的话;是否有可能通过多线程方法删除许多电子邮件,即将mailItems的集合分为4个子集;有4个线程在这些线程上运行?
我认为,因为可以通过Outlook的GUI快速删除Outlook中的多封电子邮件,所以必须有一种方法可以通过COM API进行相同的操作。
答案 0 :(得分:2)
不在OOM中-仅获得the_post_thumbnail( 'large','style=max-width:100%;height:auto;');
或MailItem.Delete
。
在扩展MAPI级别(C ++或Delphi,但不是Python)上,可以使用IMAPIFolder.DeleteMessages(带有条目ID列表)删除多条消息。或者,您可以使用IMAPIFolder.EmptyFolder(删除文件夹中的所有邮件)。
如果可以选择使用Redemption(任何语言;我是它的作者),则可以使用RDOFolder2。Items.Remove(Index)
或RDOFolder。Items。 EmptyFolder
。如果您将Outlook的RemoveMultiple
对象作为参数传递,则可以从RDOSession中检索RDOFolder
。GetRDOObjectFromOutlookObject
。
答案 1 :(得分:2)
在@Dimitry的一个很好的答案之外,我将添加一条对您可能很重要的评论:如果您在对其进行迭代时开始从Items中删除,则可能会发生奇怪的事情。 例如,在我的系统上,以下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
答案 2 :(得分:1)
上面的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”,但我发现将脚本应用于长时间使用且频繁使用的收件箱时,它更加稳定。通常,我将其与脚本结合使用,该脚本将message = inbox.Items限制在一周之内,因此不会处理整个收件箱。
答案 3 :(得分:1)
对我来说,它是通过反向迭代这些项来工作的。
旧:
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()
希望这对某人有帮助。
答案 4 :(得分:0)
我想念什么吗?尽管Dedalus指出的其余部分是正确的,但Application和NameSpace对象似乎都没有GetEntryByID方法。
命名空间对象具有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()