【实用教程】python 批量解析 EML 邮件文件 存成txt ,可以利用 AI 辅助快速生成年终总结

【实用教程】批量解析EML邮件文件,AI辅助快速生成年终总结

在年底撰写工作总结时,邮件记录是最真实的工作轨迹凭证。手动整理数十上百封邮件不仅耗时,还容易遗漏关键信息。本文将分享一个Python脚本,可批量解析EML格式邮件,自动汇总发件人、收件人、主题、正文等核心信息,生成结构化的文本报告,直接投喂AI即可快速生成高质量年终总结。

一、教程核心价值

  1. 解放双手:批量处理任意数量EML文件,无需手动打开每封邮件
  2. 结构化汇总:自动提取邮件关键信息,按统一格式整理
  3. AI友好:生成的纯文本报告可直接作为AI提示词,快速生成年终总结
  4. 编码兼容:完美解决中文邮件、中文路径乱码问题

二、环境准备

1. 安装Python

确保本地安装Python 3.7及以上版本(推荐3.9+),可从Python官网下载安装。

2. 安装依赖库

打开命令提示符(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 defdecode_email_header(header_value):"""解码邮件头(处理中文等非ASCII字符)"""ifnot header_value:return"" decoded_parts = decode_header(header_value) header_parts =[]for part, encoding in decoded_parts:ifisinstance(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)defdecode_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')defdecode_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 defextract_email_content(eml_file_path):"""解析单个EML文件(修复中文路径和编码问题)"""try:# 处理Windows中文路径问题if sys.platform =='win32': eml_file_path = win32api.GetShortPathName(eml_file_path)# 读取EML文件(使用rb模式避免编码问题)withopen(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 defsave_summary_to_txt(email_info_list, output_file_path):"""将所有解析后的邮件内容汇总保存为TXT文件"""# 确保输出目录存在 output_dir = os.path.dirname(output_file_path)if output_dir andnot os.path.exists(output_dir): os.makedirs(output_dir)withopen(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 inenumerate(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")defmain():# 配置输出文件路径 output_txt ="EML文件汇总解析结果.txt"# 获取当前文件夹下所有.eml文件(处理中文路径) current_dir = os.getcwd() eml_files =[]forfilein os.listdir(current_dir):iffile.lower().endswith('.eml'): eml_files.append(os.path.join(current_dir,file))# 检查是否找到EML文件ifnot eml_files:print("错误:当前文件夹下未找到任何.eml文件")returnprint(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❌ 解析失败的文件:")forfilein failed_files[:10]:# 只显示前10个print(f" - {file}")iflen(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()

四、使用步骤

1. 整理EML文件

将需要解析的所有EML格式邮件文件,复制到eml_summary.py脚本所在的文件夹中。

2. 运行脚本

  • Windows系统:双击eml_summary.py文件,或在脚本所在文件夹按住Shift+右键,选择“在此处打开命令窗口”,执行python eml_summary.py
  • Mac/Linux系统:打开终端,切换到脚本所在目录,执行python3 eml_summary.py

3. 查看解析结果

脚本运行完成后,会在同一目录生成EML文件汇总解析结果.txt文件,包含:

  • 汇总统计(总文件数、成功/失败数)
  • 每封邮件的完整信息(文件名、发件人、收件人、主题、日期、正文)
  • 错误提示(解析失败的文件及原因)

五、核心功能解析

1. 编码处理

  • decode_email_header:解码邮件头中的中文内容,自动适配UTF-8、GBK等编码
  • decode_email_body:处理Base64、Quoted-Printable等编码格式的邮件正文
  • 解决Windows中文路径访问问题,避免文件读取失败

2. 内容提取

  • 自动区分纯文本/HTML格式正文,HTML正文自动转为纯文本
  • 跳过邮件附件,只提取核心文本内容
  • 完整提取发件人、收件人、抄送、主题、日期等关键信息

3. 结果汇总

  • 生成结构化的TXT报告,便于阅读和AI处理
  • 详细的解析状态统计,方便排查问题

六、AI生成年终总结技巧

将生成的EML文件汇总解析结果.txt内容复制,作为提示词投喂给AI(如ChatGPT、文心一言、讯飞星火等),示例提示词:

请基于以下邮件记录,帮我生成一份2024年度工作总结,要求: 1. 总结工作成果和完成的项目 2. 分析工作中的亮点和不足 3. 提出2025年的工作计划和改进方向 4. 语言正式、逻辑清晰,分点阐述,字数约1500字 【邮件记录开始】 [粘贴TXT文件中的所有内容] 【邮件记录结束】 

AI提示词优化建议:

  1. 指定角色:“以XX岗位的身份”、“站在团队负责人的角度”
  2. 明确结构:“分为工作成果、问题反思、未来规划三部分”
  3. 突出重点:“重点体现项目推进、客户沟通、跨部门协作的工作内容”
  4. 调整风格:“语言简洁干练”、“突出数据和成果”

七、常见问题解决

1. 脚本运行提示缺少模块

执行pip install 缺失的模块名,如pip install html2text

2. 中文乱码

  • 确保脚本文件编码为UTF-8
  • Windows系统已自动设置控制台编码为UTF-8(脚本内置处理)
  • 生成的TXT文件用Notepad++等编辑器打开,选择UTF-8编码

3. 部分邮件解析失败

  • 检查EML文件是否损坏
  • 特殊格式的邮件(如加密、特殊编码)可能解析失败,可手动打开查看
  • 查看控制台的错误提示,针对性处理

八、扩展优化建议

  1. 按时间筛选:增加邮件日期筛选功能,只解析指定时间段的邮件
  2. 关键词提取:集成jieba分词,自动提取邮件中的核心关键词
  3. Excel导出:将结果导出为Excel格式,便于数据筛选和分析
  4. 分类汇总:按发件人/主题/项目自动分类邮件内容
  5. 批量导出附件:增加附件提取功能,汇总邮件中的附件文件

总结

本教程提供的EML邮件批量解析脚本,能快速将分散的邮件记录转化为结构化的文本报告,结合AI工具可大幅提升年终总结的撰写效率。不仅适用于年终总结,还可用于项目复盘、工作汇报、客户沟通记录整理等场景,是职场高效办公的实用工具。

通过简单的脚本调整,还能适配更多个性化需求,建议根据自己的工作场景优化使用,让数据整理和总结撰写更高效!

Read more

【Linux基础开发工具 (六)】Linux中的第一个系统程序——进度条Linux:详解回车、换行与缓冲区

【Linux基础开发工具 (六)】Linux中的第一个系统程序——进度条Linux:详解回车、换行与缓冲区

🎬 个人主页:艾莉丝努力练剑 ❄专栏传送门:《C语言》《数据结构与算法》《C/C++干货分享&学习过程记录》 《Linux操作系统编程详解》《笔试/面试常见算法:从基础到进阶》《Python干货分享》 ⭐️为天地立心,为生民立命,为往圣继绝学,为万世开太平 🎬 艾莉丝的简介: 🎬 艾莉丝的Linux专栏简介: 文章目录 * 5 ~> Linux中的第一个系统程序:进度条 * 5.1 两个储备知识:回车换行 / 缓冲区 * 5.1.1 回车和换行是一码事吗? * 5.1.2 缓冲区 * 5.2 观察:行缓冲区 * 5.3 练练手:demo:光标快速回退,完成倒计时功能 * 5.

By Ne0inhk
移动端也能玩转!OpenClaw iOS/Android 端部署教程,语音唤醒 + 全场景随身 AI 助手

移动端也能玩转!OpenClaw iOS/Android 端部署教程,语音唤醒 + 全场景随身 AI 助手

一、背景与价值:随身AI助手的刚需场景 随着大语言模型技术的普及,全场景AI助手的需求日益增长——无论是通勤途中的语音笔记、户外场景的实时翻译,还是离线环境下的知识查询,移动端随身AI都能解决传统桌面AI的场景局限。OpenClaw作为一款轻量级、可离线运行的开源AI框架,支持语音唤醒、多模态交互等核心功能,完美适配iOS/Android双平台部署,为用户打造真正的随身AI助手。 二、核心原理:OpenClaw移动端部署的技术逻辑 OpenClaw的移动端部署核心是将轻量化大语言模型(如Qwen-2-0.5B-Instruct)、语音唤醒模型(如PicoVoice Porcupine)与移动端推理引擎(如MLKit、TensorFlow Lite)进行整合,实现三大核心流程: 1. 低功耗语音唤醒:通过本地运行的轻量唤醒模型监听关键词,避免持续调用麦克风导致的高功耗; 2. 本地推理加速:利用移动端硬件加速(NNAPI、Core ML)运行量化后的大语言模型,实现离线交互; 3. 跨平台适配:通过Flutter或React Native统一代码底座,同时适配iOS的沙箱

By Ne0inhk
mac下的iphone镜像连接

mac下的iphone镜像连接

在 Mac 上选择用于 iPhone 镜像的手机,需先满足设备条件,再通过系统设置或镜像 App 切换,以下是具体步骤与注意事项: 前提条件 1. Mac 需搭载 Apple 芯片或 T2 安全芯片,运行 macOS Sequoia 15 及以上;iPhone 需运行 iOS 18 及以上。 2. 两台设备登录同一 Apple ID 并开启双重认证,同时打开 Wi‑Fi 与蓝牙,且距离在 10 米内。 3. iPhone 需处于锁定状态,否则无法连接镜像。 选择手机的方法 方法一:通过系统设置选择(推荐) 1. 点击

By Ne0inhk
Flutter 三方库 text 接入鸿蒙专业排版矩阵深层引擎底层适配初探:跳脱原生排印限制接管富交互组件重组重绘节点打造字级微操的高精度文字版图全量全景渲染链-适配鸿蒙 HarmonyOS ohos

Flutter 三方库 text 接入鸿蒙专业排版矩阵深层引擎底层适配初探:跳脱原生排印限制接管富交互组件重组重绘节点打造字级微操的高精度文字版图全量全景渲染链-适配鸿蒙 HarmonyOS ohos

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 三方库 text 接入鸿蒙专业排版矩阵深层引擎底层适配初探:跳脱原生排印限制接管富交互组件重组重绘节点打造字级微操的高精度文字版图全量全景渲染链 在鸿蒙应用的高度个性化文本排版、自定义 Emoji 渲染或基于位置的文本交互开发中,如何实现比原生 Text 组件更精细的控制?text 库(通常指致力于增强文本处理能力的辅助包)提供了一套底层的文本分词与样式映射工具。本文将详解该库在 OpenHarmony 上的适配要点。 前言 什么是 text?它不是简单的 UI 组件。而是对文本底层布局、字符测量以及富文本分段(Spans)的高级封装。在鸿蒙操作系统强调的“全场景智慧连接”和“极致视觉美感”背景下,利用该库可以确保你的应用在面对超长篇幅的多语言混合排版、或是需要实现“文字环绕图像”等复杂场景时,依然能提供逻辑一致、排版严密的极致呈现。 一、原理解析 1.1 基础概念

By Ne0inhk