【实用教程】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)或终端,执行以下命令安装所需依赖:

bash 复制代码
pip install html2text pywin32
  • html2text:将邮件中的HTML格式正文转为纯文本
  • pywin32:解决Windows系统中文路径访问问题

三、完整代码实现

将以下代码保存为eml_summary.py文件:

python 复制代码
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()

四、使用步骤

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工具可大幅提升年终总结的撰写效率。不仅适用于年终总结,还可用于项目复盘、工作汇报、客户沟通记录整理等场景,是职场高效办公的实用工具。

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

相关推荐
c#上位机2 小时前
C#异步编程之async、await
开发语言·c#
BoBoZz192 小时前
ExtractSelectionUsingCells选择和提取三维模型中的特定单元(Cell)
python·vtk·图形渲染·图形处理
郑州光合科技余经理2 小时前
实战分享:如何构建东南亚高并发跑腿配送系统
java·开发语言·javascript·spring cloud·uni-app·c#·php
爱装代码的小瓶子2 小时前
【c++进阶】C++11新特性:一切皆可{}初始化
开发语言·c++·visual studio
韩立学长2 小时前
【开题答辩实录分享】以《跳蚤市场二手物品交易推荐平台》为例进行选题答辩实录分享
python·django
yaoxin5211232 小时前
273. Java Stream API - Stream 中的中间操作:Mapping 操作详解
java·开发语言·python
java1234_小锋2 小时前
[免费]基于Python的Flask+Vue物业管理系统【论文+源码+SQL脚本】
后端·python·flask·物业管理
free-elcmacom2 小时前
机器学习高阶教程<5>当机器学习遇上运筹学:破解商业决策的“终极难题”
人工智能·python·机器学习
技术小甜甜2 小时前
[Python实战] 告别浏览器驱动烦恼:用 Playwright 优雅实现网页自动化
开发语言·python·自动化