Python 3.x提取纯文本邮件正文求助:非多部分邮件处理问题
解决非多部分邮件的纯文本正文提取问题
我完全懂你遇到的困扰——之前的方法只覆盖了多部分(multipart)邮件里的text/plain部分,碰到非多部分邮件时,要么拿到带HTML标签的内容,甚至直接输出完整HTML,根本不是想要的纯文本。咱们来调整一下代码,搞定这个问题。
问题根源
非多部分邮件的整个消息体就是一个单独的部分,不会进入你原来的for part in msg.walk()循环。而且有些非多部分邮件的内容类型直接是text/html,就算你直接取payload,拿到的也是带标签的HTML代码,自然会出现<br>、<p>这类元素。
改进后的解决方案
我们需要:
- 区分邮件是多部分还是非多部分类型
- 对
text/plain和text/html类型的内容分别处理 - 用HTML解析工具把HTML内容转成纯文本
- 处理编码问题避免乱码
先安装必要的依赖(用来解析HTML):
pip install beautifulsoup4
然后修改你的函数:
import email from bs4 import BeautifulSoup def getEmailMsg(mail): msg = email.message_from_string(mail) body = "" # 处理多部分邮件:遍历所有部分 if msg.is_multipart(): for part in msg.walk(): content_type = part.get_content_type() # 跳过附件和非文本类型的部分 if content_type not in ['text/plain', 'text/html']: continue # 解码payload,处理编码问题 payload = part.get_payload(decode=True) charset = part.get_content_charset() or 'utf-8' try: content = payload.decode(charset) except UnicodeDecodeError: # 编码失败时用utf-8忽略错误兜底 content = payload.decode('utf-8', errors='ignore') if content_type == 'text/plain': body += content else: # 把HTML转成纯文本,去掉所有标签 soup = BeautifulSoup(content, 'html.parser') body += soup.get_text() else: # 处理非多部分邮件:直接处理整个消息体 content_type = msg.get_content_type() payload = msg.get_payload(decode=True) charset = msg.get_content_charset() or 'utf-8' try: content = payload.decode(charset) except UnicodeDecodeError: content = payload.decode('utf-8', errors='ignore') if content_type == 'text/plain': body = content else: soup = BeautifulSoup(content, 'html.parser') body = soup.get_text() # 清理多余的空行和首尾空格 body = '\n'.join([line.strip() for line in body.splitlines() if line.strip()]) return body
关键改进点说明
- 编码处理:加入
decode=True和字符集检测,避免出现乱码;还加了Unicode解码错误的兜底方案,增强鲁棒性。 - 非多部分邮件支持:专门判断
msg.is_multipart(),如果是单部分邮件直接处理整个消息体,不会漏掉。 - HTML转纯文本:用BeautifulSoup的
get_text()方法把HTML内容转换成干净的纯文本,彻底去掉<br>、<p>、<a>这类标签。 - 文本清理:最后一步去掉多余的空行,让提取的正文更整洁。
你可以试试这个函数,不管是多部分还是非多部分邮件,应该都能提取到干净的纯文本正文了。
内容的提问来源于stack exchange,提问作者wutwut
相关产品推荐
相关产品推荐

