Вступление

Pywin32 - один из самых популярных пакетов для автоматизации вашей повседневной работы в Microsoft Outlook / Excel и т. Д. В моем предыдущем посте мы обсуждали, как использовать этот пакет для чтения электронных писем и сохранения вложений из Outlook. Поскольку в комментариях было задано довольно много вопросов, которые не были охвачены в исходном сообщении, эта статья предназначена для обзора некоторых расширенных тем для чтения электронных писем из Outlook через пакет Python Pywin32.

Если вы еще не прочитали предыдущий пост, вы можете посмотреть его здесь.

Предпосылки:

Предполагая, что вы уже установили последний пакет Pywin32 и импортировали следующие необходимые пакеты в свой сценарий, и вы не столкнетесь с какой-либо ошибкой после выполнения метода GetNamespace для установления соединения с Outlook:

import win32com.client 
#other libraries to be used in this script 
import os 
from datetime import datetime, timedelta 
outlook = win32com.client.Dispatch('outlook.application') 
mapi = outlook.GetNamespace('MAPI')

При использовании приведенного ниже кода для итерации свойства Accounts вы увидите те учетные записи, которые вы настроили в своем Outlook:

for account in mapi.Accounts:   
    print(account.DeliveryStore.DisplayName) 
#Assuming below accounts have been configured: 
#[email protected] 
#[email protected]

Теперь перейдем к темам, которые мы собираемся обсудить в этой статье.

Чтение электронной почты из нескольких учетных записей Outlook

Если у вас есть несколько учетных записей, настроенных в приложении Outlook, для доступа к одной из учетных записей вы можете использовать метод и указать имя учетной записи или индекс учетной записи, например:

for idx, folder in enumerate(mapi.Folders): 
#index starts from 1 
    print(idx+1, folder) 

#Assuming below output: 
# 1 [email protected] 
# 2 [email protected]

А для доступа к подпапкам под определенной учетной записью электронной почты вы можете продолжать использовать метод папок, чтобы указать имя подпапки или индекс папки. Перед этим вы можете проверить доступные подпапки и значение индекса, как показано ниже:

for idx, folder in enumerate(mapi.Folders("[email protected]").Folders): 
    print(idx+1, folder) 
# or using index to access the folder 
for idx, folder in enumerate(mapi.Folders(1).Folders): 
    print(idx+1, folder)

Вы увидите что-то похожее на приведенное ниже:

С указанным выше индексом и именем папки вы сможете получить доступ к сообщениям электронной почты, как показано ниже:

messages = mapi.Folders("[email protected]").Folders("Inbox").Items 
# or messages = mapi.Folders(1).Folders(2).Items 
for msg in list(messages): 
    print(msg.Subject)

Хотя индекс не изменится при перемещении вверх / вниз по папкам в Outlook, очевидно, что использование имени папки по-прежнему намного лучше индекса с точки зрения читаемости кода.

Фильтрация электронной почты на основе временного окна получения

При чтении писем из почтового ящика Outlook вы можете захотеть увеличить их в пределах определенного временного окна получения, а не сканировать тысячи писем, которые вы получили во входящем почтовом ящике. Чтобы фильтровать электронные письма на основе определенных условий, вы можете использовать этот метод вместе с логическими операторами.

Например, чтобы отфильтровать электронные письма, полученные с 1-го числа текущего месяца до сегодняшнего 00:00:

today = datetime.today() 
# first day of the month 
start_time = today.replace(month=1, hour=0, minute=0,
second=0).strftime('%Y-%m-%d %H:%M %p') 
#today 12am 
end_time = today.replace(hour=0, minute=0, 
second=0).strftime('%Y-%m-%d %H:%M %p') 
messages = messages.Restrict("[ReceivedTime] >= '" + start_time + "' And [ReceivedTime] <= '" + end_time + "'")

С помощью логических операторов, таких как и, вы можете объединить несколько критериев вместе. Например, чтобы проверить электронную почту с определенной темой, но не от определенного отправителя:

messages = messages.Restrict("[Subject] = 'Sample Report'" 
+ "And Not ([SenderEmailAddress] = '[email protected]')")

И вы также можете использовать метод Restrict сколько угодно раз, если он сделает ваш код более читабельным, чем объединение всех условий в одном фильтре, например:

messages = messages.Restrict("[Subject] = 'Sample Report'") 
messages = messages.Restrict("Not ([SenderEmailAddress] = '[email protected]')")

Получение первых N писем

При использовании метода Restrict для фильтрации сообщений электронной почты вы не сможете указать максимальное количество писем, которые хотите прочитать. Если вы хотите получить N первых / последних писем в зависимости от времени получения, вы можете использовать этот метод для сортировки сообщений на основе определенных свойств электронной почты перед тем, как разрезать список. Ниже приведен пример кода для получения последних 10 сообщений электронной почты в зависимости от времени получения:

messages.Sort("[ReceivedTime]", Descending=True) 
#read only the first 10 messages 
for message in list(messages)[:10]: 
    print(message.Subject, message.ReceivedTime, message.SenderEmailAddress)

Сопоставление подстановочных знаков для фильтрации

С помощью метода Restrict нельзя выполнять сопоставление с подстановочными знаками, например поиск, содержит ли тема или тело сообщения определенные ключевые слова. Для этого вам нужно будет использовать DASL-запрос.

Например, с помощью синтаксиса запроса DASL, приведенного ниже, вы можете отфильтровать тему электронного письма, содержащую ключевое слово «Образец отчета»:

messages = messages.Restrict("@SQL=(urn:schemas:httpmail:subject LIKE '%Sample Report%')")

Вы можете проверить здесь, чтобы увидеть, какие поля поддерживаются в запросе ADSL и какое пространство имен будет использоваться.

Включить / исключить несколько почтовых доменов

Чтобы отфильтровать электронные письма только из определенного домена, вы можете использовать запрос ADSL, аналогичный предыдущему примеру:

messages = messages.Restrict("@SQL=(urn:schemas:httpmail:SenderEmailAddress LIKE '%company.com')")

А чтобы исключить электронные письма из нескольких доменов, вы можете использовать несколько условий с логическими операторами:

messages = messages.Restrict("@SQL=(Not(urn:schemas:httpmail:senderemail LIKE '%@abc%') \
 And Not(urn:schemas:httpmail:senderemail LIKE '%@123%') \
 And Not(urn:schemas:httpmail:senderemail LIKE '%@xyz%'))")

Заключение

В этой статье мы рассмотрели некоторые расширенные возможности использования пакета Pywin32 для фильтрации электронной почты. Возможно, вы не найдете много руководств по Python для этого пакета напрямую в сети, но вы сможете увидеть эквивалентный код VBA на его официальном веб-сайте для большей части кода, который вы видели в этой статье. Если вы не можете найти решение своей проблемы, вы можете проверить, есть ли что-то реализованное в коде VBA, которое можно преобразовать в синтаксис Python.

Ссылка на предыдущий пост Чтение электронной почты из Outlook в Python.

Первоначально опубликовано на https://www.codeforests.com 16 мая 2021 г.

Больше контента на plainenglish.io