使用Python win32com读取Outlook邮件遇数字标识符错误求助
问题:遍历本地Outlook邮件时触发数字标识符安全错误
我用WinPython搭配MS Office 2019(Outlook)编写代码统计未发送邮件的工作日,代码如下:
import win32com.client import datetime # Create an instance of Outlook outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI") # Access the inbox folder inbox = outlook.GetDefaultFolder(5).Items # Set to store sent dates sent_dates = set() start_date = datetime.date(2022, 1, 1) end_date = datetime.date(2023, 1, 1) i = 0 for email in inbox: if email.Class == 43 and email.SentOn.date() >= start_date and email.SentOn.date() <= end_date: sent_dates.add(email.SentOn.date()) print("Email", i) i += 1 # Create a range of dates within the specified date range date_range = set( datetime.date.fromordinal(day) for day in range( start_date.toordinal(), end_date.toordinal() + 1 ) ) # Exclude weekends (Saturday and Sunday) date_range = { date for date in date_range if date.weekday() not in [5, 6] } # Find the workdays when you didn't send emails workdays_without_emails = date_range - sent_dates # Print workdays without sent emails print("Workdays without sent emails:") for day in sorted(workdays_without_emails): print(day)
当本地仅存储1年邮件时代码正常运行,但下载2年邮件后,遍历到约6600封邮件时触发以下错误:
Traceback (most recent call last): File "C:\Users\xxxx\Downloads\WPy64-31150\scripts\outlook2.py", line 13, in <module> if correo.Class == 43 and correo.SentOn.date() >= start_date and correo.SentOn.date() <= end_date: File "C:\Users\xxxx\Downloads\WPy64-31150\python-3.11.5.amd64\Lib\site-packages\win32com\client\dynamic.py", line 627, in __getattr__ ret = self._oleobj_.Invoke(retEntry.dispid, 0, invoke_type, 1) pywintypes.com_error: (-2147352567, 'An exception occurred.', (4096, 'Microsoft Outlook', 'The underlying security system cannot find the name of the digital identifier.', None, 0, -2146893792), None)
再次运行时,遍历到6627封邮件时触发同样错误:
Email 6624 Email 6625 Email 6626 Email 6627 Traceback (most recent call last): File "C:/Users/xxx/Downloads/WPy64-31150/scripts/outlook3.py", line 17, in <module> if email.Class == 43 and email.SentOn.date() >= start_date and email.SentOn.date() <= end_date: File "C:\Users\xxx/Downloads\WPy64-31150\python-3.11.5.amd64\Lib\site-packages\win32com\client\dynamic.py", line 627, in __getattr__ ret = self._oleobj_.Invoke(retEntry.dispid, 0, invoke_type, 1) pywintypes.com_error: (-2147352567, 'An exception occurred.', (4096, 'Microsoft Outlook', 'The underlying security system cannot find the name of the digital identifier.', None, 0, -2146893792), None)
解决建议
捕获异常跳过加密/签名邮件:错误由加密或数字签名邮件触发,读取这类邮件属性时会触发安全验证失败。在循环中加入异常捕获,跳过此类邮件:
先在顶部导入pywintypes,再修改循环代码:import win32com.client import datetime import pywintypes # 新增导入 # ... 其他代码保持不变 ... i = 0 for email in inbox: try: if email.Class == 43 and email.SentOn.date() >= start_date and email.SentOn.date() <= end_date: sent_dates.add(email.SentOn.date()) print("Email", i) i += 1 except pywintypes.com_error as e: # 匹配数字标识符相关错误码,跳过当前邮件 if -2146893792 in e.args[2]: print(f"跳过异常邮件 {i}: 数字标识符验证失败") i += 1 continue # 其他类型错误重新抛出 raise切换到已发送邮件文件夹遍历:当前代码遍历收件箱,但统计发送日期应直接访问已发送邮件文件夹(默认编号为
6),减少无效邮件遍历,同时避开收件箱中的加密邮件:
修改获取文件夹的代码:# 替换原来的inbox代码,访问已发送邮件文件夹 sent_items = outlook.GetDefaultFolder(6).Items后续循环遍历
sent_items即可,逻辑更精准,处理邮件量大幅减少。提前过滤日期范围优化性能:在遍历前用Outlook的
Restrict方法过滤目标日期内的邮件,减少循环次数:sent_items = outlook.GetDefaultFolder(6).Items sent_items.Sort("[SentOn]", True) sent_items.IncludeRecurrences = True # 构造Outlook格式的日期过滤字符串 filter_str = f"[SentOn] >= '{start_date.strftime('%m/%d/%Y')}' AND [SentOn] <= '{end_date.strftime('%m/%d/%Y')}'" filtered_items = sent_items.Restrict(filter_str)之后遍历
filtered_items即可,只处理符合日期要求的邮件。清理Outlook数字证书缓存:打开Outlook,依次进入
文件→选项→信任中心→信任中心设置→电子邮件安全→数字标识,删除无效或过期的证书,重启Outlook后再运行代码。
内容的提问来源于stack exchange,提问作者Carlos
相关产品推荐
相关产品推荐

