You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Python将PST文件转换为EML格式并保留格式与附件?

Python将PST文件转换为EML格式的实现方案

要实现PST转EML并保留格式与附件,目前有两种可靠的方案,分别适配不同环境:

方法一:使用pywin32调用Outlook COM接口(Windows环境推荐)

该方案依赖Outlook客户端的原生解析能力,能100%保留邮件的HTML格式、附件、收件人/发件人等完整信息,是最稳定的选择。

操作步骤

  1. 确保Windows系统已安装Outlook客户端
  2. 安装依赖库:pip install pywin32

代码示例

import win32com.client
import os

def pst_to_eml(pst_path, output_dir):
    # 初始化Outlook MAPI命名空间
    outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
    # 加载目标PST文件
    outlook.AddStore(pst_path)
    
    # 定位PST根文件夹
    pst_root = None
    for store in outlook.Stores:
        if store.FilePath == pst_path:
            pst_root = store.GetRootFolder()
            break
    
    if not pst_root:
        print("无法找到目标PST文件的根文件夹")
        return
    
    # 递归遍历所有邮件文件夹
    def traverse_folder(folder):
        for item in folder.Items:
            # 仅处理邮件类型项(Class=43对应MailItem)
            if item.Class == 43:
                # 处理邮件主题中的非法文件名字符
                safe_subject = item.Subject.replace('/', '_').replace('\\', '_').replace(':', '_')
                eml_path = os.path.join(output_dir, f"{safe_subject}.eml")
                # 保存为EML格式(4对应olMSGUnicode格式,实际输出标准EML)
                item.SaveAs(eml_path, 4)
        # 遍历子文件夹
        for subfolder in folder.Folders:
            traverse_folder(subfolder)
    
    # 创建输出目录
    os.makedirs(output_dir, exist_ok=True)
    traverse_folder(pst_root)
    
    # 移除加载的PST文件(可选)
    outlook.RemoveStore(pst_root)

# 使用示例
pst_to_eml("C:/Example/input.pst", "C:/Example/output_emls")

说明

  • 首次运行可能触发Outlook安全提示,需手动允许程序访问邮件数据
  • 自动保留所有附件、内嵌图片和HTML格式
  • 支持遍历PST内的所有子文件夹

方法二:使用libpff的Python绑定(跨平台)

libpff是开源的PST解析库,支持Linux、macOS等跨平台环境,但对复杂HTML格式和附件的处理能力略逊于Outlook原生方案。

操作步骤

  1. 安装libpff依赖(Linux可通过包管理器安装,Windows需下载预编译版本)
  2. 安装Python绑定:pip install pypff

代码示例

import pypff
import os

def pst_to_eml_libpff(pst_path, output_dir):
    pst = pypff.file()
    pst.open(pst_path)
    root_folder = pst.get_root_folder()
    
    # 递归遍历文件夹
    def traverse_folder(folder):
        for msg in folder.sub_messages:
            try:
                # 获取邮件原始字节流
                msg_data = msg.get_internet_message_stream()
                # 处理非法文件名
                safe_subject = msg.subject.replace('/', '_').replace('\\', '_').replace(':', '_') if msg.subject else "无主题邮件"
                eml_path = os.path.join(output_dir, f"{safe_subject}.eml")
                # 写入EML文件
                with open(eml_path, 'wb') as f:
                    f.write(msg_data)
                # 单独提取附件(可选)
                for att in msg.attachments:
                    att_path = os.path.join(output_dir, f"{safe_subject}_附件_{att.filename}")
                    with open(att_path, 'wb') as f:
                        f.write(att.read_buffer())
            except Exception as e:
                print(f"处理邮件失败:{str(e)}")
        # 遍历子文件夹
        for subfolder in folder.sub_folders:
            traverse_folder(subfolder)
    
    os.makedirs(output_dir, exist_ok=True)
    traverse_folder(root_folder)
    pst.close()

# 使用示例
pst_to_eml_libpff("/home/example/input.pst", "/home/example/output_emls")

说明

  • 跨平台无需Outlook,但对部分复杂HTML邮件的格式还原可能不完整
  • 附件需单独提取保存,可根据需求调整逻辑

注意事项

  • 格式保留优先级:优先选择pywin32方案,原生Outlook处理能完美还原所有格式细节
  • 性能:大体积PST文件建议分批次处理,避免内存占用过高
  • 权限:使用pywin32时,需确保Outlook信任该程序的访问权限

内容的提问来源于stack exchange,提问作者NobodyKnowsAboutMe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 10:13:20