У меня есть следующий код для загрузки вложений электронной почты на основе даты отправки и критериев темы электронной почты:

from datetime import date, timedelta
import os
import win32com.client


path = os.path.expanduser("C:\\Users\\xxxx\\Documents\\Projects\\VBA Projects\\VLOOKUP Automation\\Vlookup File Location")
today = date.today()

outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
inbox = outlook.Folders("xxx").Folders.Item("Inbox")
messages = inbox.Items
subject = "xxx"

dateHigh = date.today() - timedelta(days=1)
dateLow = date.today() - timedelta(days=-1)

max = 2500
for count, message in enumerate(messages):
    if count > max:
        break
    if subject in message.subject and message.senton.date() > dateLow and message.senton.date() < dateHigh:
            attachments = message.Attachments
            num_attach = len([x for x in attachments])
            for x in range(1, num_attach+1):
                attachment = attachments.Item(x)
                attachment.SaveASFile(path + '\\' + str(attachment))

Можно ли, например, указать критерии только для вложений .csv, которые нужно загрузить?

Кроме того, этот код ранее использовался в общей папке - теперь эти папки были обновлены в общие папки. После обновления мне пришлось увеличить «макс» с 500 до 2500, чтобы найти указанные электронные письма. Есть ли способ ускорить это?

Благодарность

4
Saadiq 15 Ноя 2019 в 13:24

2 ответа

Ниже приведен способ указать, какие типы файлов вы хотите.

Пожалуйста, введите окончание файла в списке attachments_of_interest.

from datetime import date, timedelta
import os
import win32com.client


path = os.path.expanduser("C:\\Users\\xxxx\\Documents\\Projects\\VBA Projects\\VLOOKUP Automation\\Vlookup File Location")
today = date.today()

outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
inbox = outlook.Folders("xxx").Folders.Item("Inbox")
messages = inbox.Items
subject = "xxx"

dateHigh = date.today() - timedelta(days=1)
dateLow = date.today() - timedelta(days=-1)

max_n = 2500
attachments_of_interest = ['.csv']

for count, message in enumerate(messages):
    if count > max_n:
        break
    if subject in message.subject and message.senton.date() > dateLow and message.senton.date() < dateHigh:
        attachments = message.Attachments
        num_attach = len([x for x in attachments])
        for x in range(1, num_attach+1):
            attachment = attachments.Item(x)
            attachment_fname = str(attachment)
            file_ending = attachment_fname.split('.')[-1]
            if not attachments_of_interest or file_ending in attachments_of_interest:
                attachment.SaveASFile(path + '\\' + attachment_fname)

Что касается ускорения, вы можете использовать пул:

from multiprocessing.pool import ThreadPool as Pool
from datetime import date, timedelta
import os
import win32com.client


path = os.path.expanduser("C:\\Users\\xxxx\\Documents\\Projects\\VBA Projects\\VLOOKUP Automation\\Vlookup File Location")
today = date.today()

outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
inbox = outlook.Folders("xxx").Folders.Item("Inbox")
messages = inbox.Items
subject = "xxx"

max_n = 2500
attachments_of_interest = ['.csv']
pool_size = 5

# define worker function before a Pool is instantiated
def worker(message):
    dateHigh = date.today() - timedelta(days=1)
    dateLow = date.today() - timedelta(days=-1)
    if subject in message.subject and message.senton.date() > dateLow and message.senton.date() < dateHigh:
        attachments = message.Attachments
        num_attach = len([x for x in attachments])
        for x in range(1, num_attach+1):
            attachment = attachments.Item(x)
            attachment_fname = str(attachment)
            file_ending = attachment_fname.split('.')[-1]
            if not attachments_of_interest or file_ending in attachments_of_interest:
                attachment.SaveASFile(path + '\\' + attachment_fname)

pool = Pool(pool_size)

for count, message in enumerate(messages):
    if count > max_n:
        break
    pool.apply_async(worker, (message,))

pool.close()
pool.join()
2
alexisdevarennes 21 Ноя 2019 в 16:19
Привет! Спасибо за ответ, однако при реализации кода кажется, что вложения вообще не сохраняются.
 – 
Saadiq
19 Ноя 2019 в 16:11
Не могли бы вы повторить попытку, я обновил свой код. Убедитесь, что расширения файлов, которые вы хотите перехватить, указаны в списке. Я обновил код, так что если список пуст, он все еще работает (для всех типов файлов)
 – 
alexisdevarennes
19 Ноя 2019 в 18:11
Эй, скопировал этот точный код и включил мое необходимое расширение. по-прежнему ничего не скачивает. Я использовал свой старый код, чтобы проверить его на тех же электронных письмах и вложениях, которые загружаются, хотя и в формате pdf, и в xlsx, где мне, очевидно, просто нужен xlsx. но просто чтобы подтвердить, что нет другой проблемы
 – 
Saadiq
20 Ноя 2019 в 11:44
Не могли бы вы распечатать, как выглядит attachment_fname, и привести несколько примеров? Это поможет мне отладить, немного сложно сделать это без вашей настройки (на ubuntu, и у меня нет перспектив)
 – 
alexisdevarennes
20 Ноя 2019 в 12:09
Привет, по имени attachment_fname, вы хотите, чтобы я предоставил вам полное имя файла и расширение, как оно указано в электронном письме? Я не совсем понимаю, о чем вы говорите
 – 
Saadiq
20 Ноя 2019 в 16:02

Я думаю, что это является частью требования для загрузки только CSV. Этот компонент Outlook имеет несколько методов, которые вы можете использовать. Вместо messages = inbox.Items попробуйте messages = inbox.Items.GetFirst () и получите первое сообщение, затем используйте

Messages = inbox.Items.oItems.GetNext (), таким образом, у вас всегда есть одно сообщение в памяти, и вы можете продолжать цикл в течение более длительного времени.

Убедитесь, что у вас есть Microsoft Outlook 16.0 Object Library или выше, чтобы этот метод существовал. GetFirst () C # код, используемый мной

Outlook.MailItem oMsg = (Outlook.MailItem)oItems.GetFirst();

                    //Output some common properties.
                    Console.WriteLine(oMsg.Subject);
                    Console.WriteLine(oMsg.SenderName);
                    Console.WriteLine(oMsg.ReceivedTime);
                    Console.WriteLine(oMsg.Body);

                    //Check for attachments.
                    int AttachCnt = oMsg.Attachments.Count;
                    Console.WriteLine("Attachments: " + AttachCnt.ToString());
                Outlook.MailItem oMsg1 = (Outlook.MailItem)oItems.GetNext();
0
Jin Thakur 25 Ноя 2019 в 23:29