批量解析 EML 邮件文件,AI 辅助快速生成年终总结
在年底撰写工作总结时,邮件记录是最真实的工作轨迹凭证。手动整理数十上百封邮件不仅耗时,还容易遗漏关键信息。本文将分享一个 Python 脚本,可批量解析 EML 格式邮件,自动汇总发件人、收件人、主题、正文等核心信息,生成结构化的文本报告,直接投喂 AI 即可快速生成高质量年终总结。
教程核心价值
- 解放双手:批量处理任意数量 EML 文件,无需手动打开每封邮件
Python 脚本批量解析 EML 邮件文件,提取发件人、收件人、主题及正文等核心信息,解决中文路径和编码乱码问题。生成的结构化文本报告可直接作为 AI 提示词,辅助快速撰写高质量年终总结,提升职场办公效率。支持 Windows 中文路径处理及多种邮件编码格式兼容,适用于项目复盘、工作汇报等场景。
在年底撰写工作总结时,邮件记录是最真实的工作轨迹凭证。手动整理数十上百封邮件不仅耗时,还容易遗漏关键信息。本文将分享一个 Python 脚本,可批量解析 EML 格式邮件,自动汇总发件人、收件人、主题、正文等核心信息,生成结构化的文本报告,直接投喂 AI 即可快速生成高质量年终总结。
确保本地安装 Python 3.7 及以上版本(推荐 3.9+),可从 Python 官网下载安装。
打开命令提示符(CMD)或终端,执行以下命令安装所需依赖:
pip install html2text pywin32
html2text:将邮件中的 HTML 格式正文转为纯文本pywin32:解决 Windows 系统中文路径访问问题将以下代码保存为 eml_summary.py 文件:
import email
import quopri
import base64
import html2text
from email.header import decode_header
import os
import glob
from datetime import datetime
import sys
# 解决中文路径问题
if sys.platform == 'win32':
import win32api
import win32con
def decode_email_header(header_value):
"""解码邮件头(处理中文等非 ASCII 字符)"""
if not header_value:
return ""
decoded_parts = decode_header(header_value)
header_parts = []
for part, encoding in decoded_parts:
if isinstance(part, bytes):
if encoding:
header_parts.append(part.decode(encoding, errors='replace'))
else:
# 尝试常见编码
try:
header_parts.append(part.decode('utf-8'))
except:
try:
header_parts.append(part.decode('gbk'))
except:
header_parts.append(part.decode('latin-1'))
else:
header_parts.append(part)
return ''.join(header_parts)
def decode_base64_content(content, charset='utf-8'):
"""专门解码 base64 编码的邮件正文"""
try:
# 先解码 base64
decoded_bytes = base64.b64decode(content)
# 再解码字符集
return decoded_bytes.decode(charset, errors='replace')
except Exception as e:
try:
return decoded_bytes.decode('gbk', errors='replace')
except:
return decoded_bytes.decode('latin-1', errors='replace')
def decode_email_body(part):
"""解码邮件正文内容(增强版)"""
# 获取原始 payload
payload = part.get_payload(decode=False)
charset = part.get_content_charset() or 'utf-8'
# 处理不同的传输编码
transfer_encoding = part.get('Content-Transfer-Encoding', '').lower()
if transfer_encoding == 'base64':
# 专门处理 base64 编码
text = decode_base64_content(payload, charset)
elif transfer_encoding == 'quoted-printable':
# 处理 quoted-printable 编码
decoded_bytes = quopri.decodestring(payload)
try:
text = decoded_bytes.decode(charset, errors='replace')
except:
text = decoded_bytes.decode('gbk', errors='replace')
else:
# 普通编码
try:
text = payload.decode(charset, errors='replace')
except:
try:
text = payload.decode('gbk', errors='replace')
except:
text = payload.decode('latin-1', errors='replace')
return text
def extract_email_content(eml_file_path):
"""解析单个 EML 文件(修复中文路径和编码问题)"""
try:
# 处理 Windows 中文路径问题
if sys.platform == 'win32':
eml_file_path = win32api.GetShortPathName(eml_file_path)
# 读取 EML 文件(使用 rb 模式避免编码问题)
with open(eml_file_path, 'rb') as f:
msg = email.message_from_bytes(f.read())
# 提取邮件基本信息
email_info = {
'文件名': os.path.basename(eml_file_path),
'发件人': decode_email_header(msg.get('From', '')),
'收件人': decode_email_header(msg.get('To', '')),
'抄送': decode_email_header(msg.get('Cc', '')),
'主题': decode_email_header(msg.get('Subject', '')),
'邮件日期': decode_email_header(msg.get('Date', '')),
'正文': '',
'解析状态': '成功'
}
# 提取正文内容
body_text = ""
body_html = ""
# 遍历邮件部分
if msg.is_multipart():
for part in msg.walk():
content_type = part.get_content_type()
content_disposition = str(part.get("Content-Disposition"))
# 跳过附件
if "attachment" in content_disposition:
continue
# 提取纯文本内容
if content_type == "text/plain":
body_text = decode_email_body(part)
# 提取 HTML 内容(后续转为文本)
elif content_type == "text/html":
body_html = decode_email_body(part)
else:
# 非多部分邮件
content_type = msg.get_content_type()
if content_type == "text/plain":
body_text = decode_email_body(msg)
elif content_type == "text/html":
body_html = decode_email_body(msg)
# 优先使用纯文本,若无则将 HTML 转为文本
if body_text:
email_info['正文'] = body_text
elif body_html:
# 将 HTML 转为纯文本(优化配置)
h2t = html2text.HTML2Text()
h2t.ignore_links = False
h2t.ignore_images = True
h2t.unicode_snob = True
h2t.body_width = 0
email_info['正文'] = h2t.handle(body_html)
except Exception as e:
# 详细记录错误信息
error_msg = f'失败:{str(e)}'
email_info = {
'文件名': os.path.basename(eml_file_path),
'解析状态': error_msg,
'发件人': '',
'收件人': '',
'抄送': '',
'主题': '',
'邮件日期': '',
'正文': ''
}
print(f"解析 {os.path.basename(eml_file_path)} 出错:{error_msg}")
return email_info
def save_summary_to_txt(email_info_list, output_file_path):
"""将所有解析后的邮件内容汇总保存为 TXT 文件"""
# 确保输出目录存在
output_dir = os.path.dirname(output_file_path)
if output_dir and not os.path.exists(output_dir):
os.makedirs(output_dir)
with open(output_file_path, 'w', encoding='utf-8', errors='replace') as f:
# 写入汇总标题
f.write("=" * 80 + "\n")
f.write(f"EML 文件批量解析汇总报告\n")
f.write(f"汇总时间:{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
f.write(f"解析文件总数:{len(email_info_list)}\n")
f.write(f"成功解析数:{len([x for x in email_info_list if x['解析状态']=='成功'])}\n")
f.write(f"失败解析数:{len([x for x in email_info_list if x['解析状态']!='成功'])}\n")
f.write("=" * 80 + "\n\n")
# 遍历每个邮件的解析结果
for idx, email_info in enumerate(email_info_list, 1):
f.write(f"【第{idx}个文件】\n")
f.write("-" * 60 + "\n")
# 写入该邮件的所有信息
for key, value in email_info.items():
if value:
# 只写入非空内容
if key == '正文':
f.write(f"{key}:\n{value}\n\n")
else:
f.write(f"{key}:{value}\n")
# 每个文件之间的分隔符
f.write("\n" + "=" * 80 + "\n\n")
def main():
# 配置输出文件路径
output_txt = "EML 文件汇总解析结果.txt"
# 获取当前文件夹下所有.eml 文件(处理中文路径)
current_dir = os.getcwd()
eml_files = []
for file in os.listdir(current_dir):
if file.lower().endswith('.eml'):
eml_files.append(os.path.join(current_dir, file))
# 检查是否找到 EML 文件
if not eml_files:
print("错误:当前文件夹下未找到任何.eml 文件")
return
print(f"找到 {len(eml_files)} 个.eml 文件,开始批量解析...")
print("-" * 50)
# 批量解析每个 EML 文件
email_info_list = []
for eml_file in eml_files:
print(f"正在解析:{os.path.basename(eml_file)}")
email_content = extract_email_content(eml_file)
email_info_list.append(email_content)
# 打印解析状态
status = "✅ 成功" if email_content['解析状态'] == '成功' else "❌ 失败"
print(f"状态:{status}")
# 保存汇总结果
print("\n正在保存汇总结果...")
save_summary_to_txt(email_info_list, output_txt)
# 输出汇总信息
print("-" * 50)
print(f"批量解析完成!")
print(f"汇总结果已保存至:{os.path.abspath(output_txt)}")
print(f"📊 汇总统计:")
print(f" 总文件数:{len(eml_files)}")
success_count = len([x for x in email_info_list if x['解析状态'] == '成功'])
fail_count = len([x for x in email_info_list if x['解析状态'] != '成功'])
print(f" 成功解析:{success_count}")
print(f" 失败解析:{fail_count}")
# 输出失败的文件列表(如果有)
failed_files = [x['文件名'] for x in email_info_list if x['解析状态'] != '成功']
if failed_files:
print(f"\n❌ 解析失败的文件:")
for file in failed_files[:10]: # 只显示前 10 个
print(f" - {file}")
if len(failed_files) > 10:
print(f" - ... 还有 {len(failed_files)-10} 个文件解析失败")
if __name__ == "__main__":
# 设置系统编码
if sys.platform == 'win32':
os.system('chcp 65001 > nul')
# 设置控制台编码为 UTF-8
# 安装依赖(首次运行时取消注释执行)
# os.system("pip install html2text pywin32")
main()
将需要解析的所有 EML 格式邮件文件,复制到 eml_summary.py 脚本所在的文件夹中。
eml_summary.py 文件,或在脚本所在文件夹按住 Shift+右键,选择'在此处打开命令窗口',执行 python eml_summary.pypython3 eml_summary.py脚本运行完成后,会在同一目录生成 EML 文件汇总解析结果.txt 文件,包含:
decode_email_header:解码邮件头中的中文内容,自动适配 UTF-8、GBK 等编码decode_email_body:处理 Base64、Quoted-Printable 等编码格式的邮件正文将生成的 EML 文件汇总解析结果.txt 内容复制,作为提示词投喂给 AI(如 ChatGPT、文心一言、讯飞星火等),示例提示词:
请基于以下邮件记录,帮我生成一份 2024 年度工作总结,要求:
1. 总结工作成果和完成的项目
2. 分析工作中的亮点和不足
3. 提出 2025 年的工作计划和改进方向
4. 语言正式、逻辑清晰,分点阐述,字数约 1500 字
【邮件记录开始】
[粘贴 TXT 文件中的所有内容]
【邮件记录结束】
执行 pip install 缺失的模块名,如 pip install html2text
本教程提供的 EML 邮件批量解析脚本,能快速将分散的邮件记录转化为结构化的文本报告,结合 AI 工具可大幅提升年终总结的撰写效率。不仅适用于年终总结,还可用于项目复盘、工作汇报、客户沟通记录整理等场景,是职场高效办公的实用工具。
通过简单的脚本调整,还能适配更多个性化需求,建议根据自己的工作场景优化使用,让数据整理和总结撰写更高效!

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online