Python遍历Outlook邮件仅返回首个结果问题及代码修正求助
Outlook邮件遍历不完整问题修复
我编写了一段Python代码用于遍历Outlook指定文件夹中的邮件,但仅能获取首个匹配结果,其余结果需重新遍历才能返回。后续对代码进行两次修订后,仍存在遍历不完整的问题,相关代码及问题分析如下:
初始代码
mail = win32com.client.Dispatch('outlook.application').GetNamespace("MAPI") inbox = mail.GetDefaultFolder(6).Folders["Trial"] df = pd.read_excel(r"C://User//Asus//Test//Test.xlsx", sheet_name = 'Sheet1') mail = df.iloc[:,0].tolist() #this is the list of emails i.e. ends with gmail.com processed = mail.GetDefaultFolder(6).Folders["Trial"].Folders["Done"] msg = inbox.Items.GetFirst() add = msg.SenderEmailAddress for attch in msg.Attachments: if any([add.endswith(m) for m in mail]) and attch.FileName[-3:] != 'png': fname = attch.FileName dir = "C://User//Asus//Output//" tempdir = os.path.join(dir, fname) attch.SaveAsFile(tempdir) msg.Move(processed) #move the emails that completed processed to another folder
问题:仅调用GetFirst()获取单封邮件,未循环遍历所有邮件,自然只能处理第一个结果。此外,变量mail被覆盖为邮件列表,后续processed = mail.GetDefaultFolder(...)会直接报错,因为列表没有该方法。
更新代码V1
mail = win32com.client.Dispatch('outlook.application').GetNamespace("MAPI") inbox = mail.GetDefaultFolder(6).Folders["Trial"] df = pd.read_excel(r"C://User//Asus//Test//Test.xlsx", sheet_name = 'Sheet1') mail = df.iloc[:,0].tolist() #this is the list of emails i.e. ends with gmail.com processed = mail.GetDefaultFolder(6).Folders["Trial"].Folders["Done"] add = msg.SenderEmailAddress for msg in inbox.Items: print(msg.Subject) for attch in msg.Attachments: if any([add.endswith(m) for m in mail]) and attch.FileName[-3:] != 'png': fname = attch.FileName dir = "C://User//Asus//Output//" tempdir = os.path.join(dir, fname) attch.SaveAsFile(tempdir) msg.Move(processed) #move the emails that completed processed to another folder
问题:
- 变量名冲突:
mail先指向Outlook MAPI对象,后被覆盖为邮件列表,导致processed定义报错。 add变量在循环外初始化,始终使用第一封邮件的发件人地址,判断逻辑完全错误。- 遍历附件时立即移动邮件,Outlook的
Items是动态集合,移动邮件会导致集合索引变化,后续遍历会跳过部分邮件。
更新代码V2
for msg in inbox.Items: try: for attch in msg.Attachments: if msg.SenderEmailType == "SMTP" and attch.FileName[-3:] != 'png': add = msg.SenderEmailAddress print(add, "address") fname = attch.FileName dir = "C://User//Asus//Output//" tempdir = os.path.join(dir, fname) attch.SaveAsFile(tempdir) msg.Move(processed) elif msg.SenderEmailType == "EX" and attch.FileName[-3:] != 'png': add = msg.Sender.GetExchangeUser().PrimarySmtpAddress print(add, "address") fname = attch.FileName dir = "C://User//Asus//Output//" tempdir = os.path.join(dir, fname) attch.SaveAsFile(tempdir) msg.Move(processed) except Exception as e: print(e) continue
问题:
- 处理单个附件后立即移动邮件,同一邮件的多个附件会重复触发移动操作,且邮件移走后集合变化,导致遍历中断。
- 丢失了原需求中仅处理指定gmail.com列表发件人邮件的判断逻辑。
- 未提前将
Items转换为静态列表,动态集合的修改仍会导致遍历不完整。
修复后的完整代码
import win32com.client import pandas as pd import os # 初始化Outlook对象 outlook = win32com.client.Dispatch('outlook.application').GetNamespace("MAPI") # 指定目标文件夹 inbox = outlook.GetDefaultFolder(6).Folders["Trial"] # 已处理邮件存放文件夹 processed_folder = outlook.GetDefaultFolder(6).Folders["Trial"].Folders["Done"] # 读取需要处理的发件人邮箱列表 df = pd.read_excel(r"C:/User/Asus/Test/Test.xlsx", sheet_name='Sheet1') target_emails = df.iloc[:,0].tolist() # 避免变量名冲突,改用target_emails # 输出目录 output_dir = r"C:/User/Asus/Output/" os.makedirs(output_dir, exist_ok=True) # 确保目录存在 # 将Items转换为静态列表,避免遍历中集合变化导致跳过 messages = list(inbox.Items) for msg in messages: try: # 获取正确的发件人邮箱地址 if msg.SenderEmailType == "SMTP": sender_email = msg.SenderEmailAddress elif msg.SenderEmailType == "EX": exchange_user = msg.Sender.GetExchangeUser() sender_email = exchange_user.PrimarySmtpAddress if exchange_user else "" else: sender_email = "" # 判断是否为目标发件人 if not any(sender_email.endswith(email) for email in target_emails): continue # 处理所有符合条件的附件 attachment_saved = False for attch in msg.Attachments: # 排除png格式附件(统一小写判断,避免大小写问题) if not attch.FileName.lower().endswith('png'): fname = attch.FileName temp_path = os.path.join(output_dir, fname) attch.SaveAsFile(temp_path) attachment_saved = True print(f"已保存附件: {fname}") # 只有成功保存附件才移动邮件 if attachment_saved: msg.Move(processed_folder) print(f"已移动邮件: {msg.Subject}") except Exception as e: print(f"处理邮件出错: {str(e)}") continue
修复说明:
- 避免变量名冲突,将Outlook对象命名为
outlook,邮件列表命名为target_emails。 - 将
inbox.Items转换为静态列表messages,遍历过程中集合变化不会影响遍历完整性。 - 先判断发件人是否在目标列表,再处理所有附件,最后统一移动邮件,避免多次移动或集合中断。
- 增加目录创建逻辑,确保输出目录存在。
- 统一判断附件后缀为小写,避免大小写匹配问题。
内容的提问来源于stack exchange,提问作者mayliew
相关产品推荐
相关产品推荐

