Python中如何将BytesParser解析的EmailMessage转为字典?
将EmailMessage对象转换为字典的简便方法
问题背景
我在Python中处理如下格式的邮件字符串:
email_str = 'Message-ID: <9803411.1075852365218.JavaMail.evans@thyme>\nDate: Thu, 24 May 2001 15:27:00 -0700 (PDT)\nFrom: john.forney@enron.com\nSubject: Send in your registration card\nMime-Version: 1.0\nContent-Type: text/plain; charset=us-ascii\nContent-Transfer-Encoding: 7bit\nX-From: John M Forney <John M Forney/HOU/ECT@Enron>\nX-To: \nX-cc: \nX-bcc: \nX-Folder: \\JFORNEY (Non-Privileged)\\Forney, John M.\\To Do\nX-Origin: FORNEY-J\nX-FileName: JFORNEY (Non-Privileged).pst\n\n\tTASK ASSIGNMENT\n\n\nTask Priority:\t\t1\nTask Due On:\t\t\nTask Start Date:\t\n\nFill out and return your registration card or register by phone or fax today!\n\nOnly registered users get:\n-FREE technical support\n-SPECIAL OFFERS on Palm III accessories and add-ons\n-SNEAK PREVIEWS of new product enhancements and software releases\n\nYour registration card also serves as proof of purchase for:\n-Discounts on product upgrades\n-Warranty coverage'
使用email.parser模块的BytesParser解析后得到EmailMessage对象,它支持类似字典的键访问,但并非真正的字典。我希望将其转换为标准字典以便后续操作,目前手动编写了提取字段的函数:
def extract_fields_from_msg(msg): fields = { 'Message-ID': msg['Message-ID'], 'Date': msg['Date'], 'From': msg['From'], 'Subject': msg['Subject'], 'Mime-Version': msg['Mime-Version'], 'Content-Type': msg['Content-Type'], 'Content-Transfer-Encoding': msg['Content-Transfer-Encoding'], 'X-From': msg['X-From'], 'X-To': msg['X-To'], 'X-cc': msg['X-cc'], 'X-bcc': msg['X-bcc'], 'X-Folder': msg['X-Folder'], 'X-Origin': msg['X-Origin'], 'X-FileName': msg['X-FileName'], 'Body': msg.get_body(preferencelist=('plain')).get_content() if msg.get_body(preferencelist=('plain')) else None } return fields # 注:原函数遗漏return语句,此处补全
想知道是否有更简便的自动转换方法,比如利用EmailMessage已有的.keys()方法,实现类似字典的批量转换。
解决方案
当然有更简便的方式,无需手动枚举所有头部字段:
1. 批量提取所有头部字段
EmailMessage对象的.keys()方法可以返回所有头部字段的名称,结合字典推导式就能自动提取所有键值对,再单独处理正文内容:
def msg_to_dict(msg): # 自动提取所有头部字段 email_dict = {key: msg[key] for key in msg.keys()} # 处理纯文本正文 plain_body = msg.get_body(preferencelist=('plain')) email_dict['Body'] = plain_body.get_content() if plain_body else None return email_dict
2. 处理多值头部字段
如果某些头部存在多个值(比如To包含多个收件人),直接用msg[key]只会返回第一个值,这时可以改用.get_all(key)获取所有值(返回列表):
def msg_to_dict_with_multivalue(msg): email_dict = {key: msg.get_all(key) for key in msg.keys()} plain_body = msg.get_body(preferencelist=('plain')) email_dict['Body'] = plain_body.get_content() if plain_body else None return email_dict
3. 过滤特定字段(可选)
如果只需要部分头部字段,也可以在推导式中添加过滤条件,比如只保留指定字段:
def msg_to_filtered_dict(msg, include_fields=None): if include_fields is None: include_fields = ['Message-ID', 'Date', 'From', 'Subject', 'Body'] # 提取指定头部字段 email_dict = {key: msg[key] for key in msg.keys() if key in include_fields} # 单独处理Body(如果在包含列表中) if 'Body' in include_fields: plain_body = msg.get_body(preferencelist=('plain')) email_dict['Body'] = plain_body.get_content() if plain_body else None return email_dict
这些方法都能避免手动逐个编写字段,提升代码的可维护性,尤其是当邮件包含自定义头部(比如示例中的X-开头字段)时,自动提取会更高效。
内容的提问来源于stack exchange,提问作者Narges Ghanbari
相关产品推荐
相关产品推荐

