python win32com: удаление нескольких писем в Outlook - PullRequest
0 голосов
/ 28 ноября 2018

Мне нужно удалить несколько сообщений электронной почты в Outlook из python через модуль win32com.

Я понимаю, что есть метод VBA MailItem.Delete (), доступный для win32com через COM, и он работает;но это ОЧЕНЬ ОЧЕНЬ медленно при удалении более одного электронного письма, так как нужно будет удалять электронные письма последовательно, то есть перебирать коллекцию писем MailItem.

Есть ли способ удалить выбранную коллекцию mailItems сразу, что-то вроде MailItemCollection.DeleteAll ()?

Также, если вышеуказанное невозможно;Можно ли вообще удалить много писем с помощью многопоточного подхода, т.е. разделить коллекцию mailItems на, скажем, 4 подмножества;4 темы работают на них?

Я полагаю, поскольку я могу очень быстро удалить несколько электронных писем в outlook через его графический интерфейс, должен быть способ, с помощью которого я могу сделать то же самое через COM API.

Ответы [ 3 ]

0 голосов
/ 20 января 2019

В дополнение к отличному ответу @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 и затем удаление поиска по идентификатору:

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()

Я думаю, что производительность еще хуже, хотяс

0 голосов
/ 15 мая 2019

Отличный ответ от Дедала выше.Хотелось сделать более краткую версию кода:

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

Возможно, вам не понадобятся две "попытки", но я обнаружил, что он был более стабильным при применении сценария к длинным и интенсивно используемым входящим сообщениям.Обычно я комбинирую это со скриптом, который ограничивает message = inbox.Items с точностью до недели, поэтому он не делает всю входящую почту.

0 голосов
/ 28 ноября 2018

Не в OOM - MailItem.Delete или Items.Remove(Index) - это все, что вы получаете.

На расширенном уровне MAPI (C ++ или Delphi, но не Python) вы можете удалять несколько сообщений, используя IMAPIFolder.DeleteMessages (который принимает список идентификаторов записей).Или вы можете использовать IMAPIFolder.EmptyFolder (удаляет все сообщения в папке).

При использовании Выкуп (любой язык; я его автор) является опцией,Вы можете использовать RDOFolder2 . EmptyFolder или RDOFolder . Items . RemoveMultiple.RDOFolder можно получить из RDOSession . GetRDOObjectFromOutlookObject, если вы передаете объект Outlook MAPIFolder в качестве параметра.

...