Python多处理器与PyWin32实现更快的批量电子邮件处理



我有一项任务,我需要处理保存在我的机器上的.pst文件中的大约20000封电子邮件-但最终这些电子邮件将通过API移动-我需要处理每封电子邮件,并将其数据放入一个适当格式的POST请求中。理想情况下,我希望通过使用Python的多处理模块来加快这个过程。

我对win32com模块的理解是,一旦你查看了电子邮件的Items对象,你就可以迭代每封电子邮件——我以前用for循环等做过这件事。然而,当我在map((函数中将其作为可迭代对象引入时,程序似乎什么都不做。

如果有人能阐明如何使用多处理将映射函数应用于来自win32com模块的一组outlook电子邮件,那将非常有帮助。

提前感谢

from multiprocessing import Pool
import time
import win32com.client
def f(x):
print(x.Subject)
## More processing logic - producing a dict with data in the right format ##
return processed_email
if __name__ == '__main__':
start_time = time.time()
outlook = win32com.client.Dispatch("Outlook.Application")
mapi = outlook.GetNamespace("MAPI")
OutlookDataIndex = 4 # folder of interest
folder = mapi.Folders.Item(OutlookDataIndex).Folders["Emails"]
emails = folder.Items
results = []
with Pool(5) as p:
results = (p.map(f, emails))

经过一段时间的研究,我找到了一个解决方法-

while文件夹。项是可迭代的,当脚本遍历项时,它实际上正在与outlook应用程序交互。因此,让多个cpu与win32com.client的同一实例交互是行不通的。

为了实现这一点,我使用num_emails = len(folder.Items)调整了文件夹的大小,然后为每个核心实例化了一个新的win32com.client,使用range(num_emails)作为map()函数中的可迭代对象。然后,可以使用迭代中的索引对电子邮件项目进行索引。

重新实例化客户端确实感觉有点冗长,并且可以通过将文件夹索引等传递给函数来提高可靠性——然而,就这项任务而言,它已经在中工作了

import multiprocessing
import time
import win32com.client
def f(x):
outlook = win32com.client.Dispatch("Outlook.Application")
mapi = outlook.GetNamespace("MAPI")
# Locate the "Outlook Data File/ToSend" folder
OutlookDataIndex = 4
folder = mapi.Folders.Item(OutlookDataIndex).Folders["Test Set"]
emails = folder.Items
email = emails[x]
## More processing logic - producing a dict with data in the right format ##
return processed_email
if __name__ == '__main__':
try:
cpus = multiprocessing.cpu_count()
except NotImplementedError:
cpus = 2
print(cpus)
start_time = time.time()
outlook = win32com.client.Dispatch("Outlook.Application")
mapi = outlook.GetNamespace("MAPI")
# Locate the "Outlook Data File/ToSend" folder
OutlookDataIndex = 4
folder = mapi.Folders.Item(OutlookDataIndex).Folders["Test Set"]
emails = folder.Items
sum_emails = len(emails)
results = []
pool = multiprocessing.Pool(processes=cpus)
results = pool.map(f, range(sum_emails))
print(results)

最新更新