如何用正则删除邮件正文关键词后内容并修复Python读Outlook报错
报错根因
- 代码缩进错误:读取正文的逻辑写在了for循环外部,循环仅执行了取message的单条语句,遍历结束后
message指向文件夹内排序最靠前的条目。Outlook文件夹内除普通邮件外,还可能存在会议请求、送达回执、系统通知等非邮件类条目,这类条目不存在正文属性,直接访问就会触发AttributeError。 - 属性名大小写不匹配:通过win32com调用Outlook COM接口时,属性名严格区分大小写,邮件正文的标准属性名为首字母大写的
Body,全小写的body无法被COM对象识别。 - 正则规则覆盖不全:原有正则仅能匹配Regards后跟随2行内容的固定格式签名,无法适配不同长度、不同换行格式的签名场景。
- 存在误操作风险:原代码直接给
message.body赋值,会尝试修改Outlook中存储的原邮件正文,容易导致本地邮件内容被意外篡改。
修复步骤
- 调整代码缩进,把邮件正文读取、清洗的逻辑全部放到for循环内部,每遍历到一个条目先校验类型,非邮件类条目直接跳过。
- 所有正文属性访问统一使用
Body,匹配COM接口的属性命名规则。 - 优化正则规则,使用
Regards[\s\S]*匹配从Regards关键词开始到正文末尾的所有内容,增加忽略大小写匹配,兼容regards、REGARDS等不同写法。 - 取消对原邮件对象的属性赋值,清洗后的正文单独存入变量,用于后续字段提取和DataFrame写入,避免修改本地原邮件。
- 增加正文空值判断,遇到无正文的空白邮件时不会触发报错。
修复后参考代码
import win32com.client import re import pandas as pd EMAIL_SUBJ_SEARCH_STRING = 'SGEPSBSH Index Level' EMAIL_CONTNT = {'Ticker': [], 'TickerLevel': [], 'DATE': []} # Outlook 普通邮件类型常量 OL_MAIL_ITEM = 43 # 初始化Outlook连接 out_app = win32com.client.gencache.EnsureDispatch("Outlook.Application") out_namespace = out_app.GetNamespace("MAPI") root_folder = out_namespace.GetDefaultFolder(6) out_iter_folder = root_folder.Folders['Email_snapper'] item_count = out_iter_folder.Items.Count if item_count > 0: # 取最新2封邮件遍历 for i in range(item_count, max(0, item_count - 2), -1): message = out_iter_folder.Items[i] # 跳过非邮件条目 if message.Class != OL_MAIL_ITEM: continue # 跳过主题不匹配的邮件 if EMAIL_SUBJ_SEARCH_STRING not in message.Subject: continue # 读取原始正文,兼容空正文场景 raw_body = message.Body if message.Body else "" # 清洗签名:删除从Regards开始的所有后续内容,忽略大小写 cleaned_body = re.sub(r"Regards[\s\S]*", "", raw_body, flags=re.IGNORECASE) print("清洗后正文:\n", cleaned_body) # 后续可在cleaned_body中通过正则提取日期、SGEPSBSH指数值、bbg level # 提取完成后将值追加到EMAIL_CONTNT对应列表,最终通过pd.DataFrame(EMAIL_CONTNT)生成目标DataFrame
内容的提问来源于stack exchange,提问作者Rahul Vaidya
相关产品推荐
相关产品推荐

