使用Python与pypff提取PST邮件元数据遇阻:无法获取收件人信息
解决PST文件元数据提取(收件人)及.msg导出问题
一、提取收件人信息
pypff库的message对象提供了recipients属性来获取收件人列表,每个收件人对象包含name(姓名)和email_address(邮箱地址)字段。你需要遍历该列表收集所有收件人信息,同时可以补充提取邮件内容,修改原有代码即可实现:
# Retrieving E-Mails from a PST file #File opening #Fist we load the libraries import pypff import pandas as pd import matplotlib.pyplot as plt import seaborn as sns #Then we open the file: the opening can neverthless be quite long #depending on the size of the archive. pst = pypff.file() pst.open("PathTo.pst") # Metadata extraction #It is possible to navigate through the structure using the functions offered by the library, from the root: root = pst.get_root_folder() #To extract the data, a recursive function is necessary: def parse_folder(base): messages = [] for folder in base.sub_folders: if folder.number_of_sub_folders: messages += parse_folder(folder) print(folder.name) for message in folder.sub_messages: # 提取收件人信息 recipients = [] for recipient in message.recipients: # 拼接姓名和邮箱,处理空值情况 recipient_info = f"{recipient.name or 'Unknown'} <{recipient.email_address or 'No Email'}>" recipients.append(recipient_info) # 提取邮件内容,优先取纯文本,无则取HTML body = message.plain_text_body if message.plain_text_body else message.html_body messages.append({ "subject": message.subject, "sender": message.sender_name, "datetime": message.client_submit_time, "recipients": ", ".join(recipients), # 用逗号分隔多个收件人 "body": body }) return messages messages = parse_folder(root) # 转换为DataFrame方便查看和处理 df = pd.DataFrame(messages) print(df.head())
二、导出PST中的邮件为.msg文件
pypff本身不支持直接导出.msg文件,Windows环境下可以通过pywin32调用Outlook的COM对象实现,步骤如下:
- 先安装依赖:
pip install pywin32 - 运行以下代码:
import win32com.client import os def export_pst_to_msg(pst_path, output_dir): # 创建输出目录 if not os.path.exists(output_dir): os.makedirs(output_dir) outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI") # 添加PST文件到Outlook配置文件 pst_store = outlook.AddStore(pst_path) try: # 获取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 export_folder(folder, parent_path): current_path = os.path.join(parent_path, folder.Name) if not os.path.exists(current_path): os.makedirs(current_path) # 导出当前文件夹的邮件(Class=43代表邮件对象) for item in folder.Items: if item.Class == 43: # 替换主题中的非法字符,避免保存失败 filename = f"{item.Subject}.msg".replace("/", "_").replace("\\", "_").replace(":", "_").replace("*", "_").replace("?", "_").replace('"', "_").replace("<", "_").replace(">", "_").replace("|", "_") save_path = os.path.join(current_path, filename) item.SaveAs(save_path, 3) # 3表示MSG格式 # 处理子文件夹 for subfolder in folder.Folders: export_folder(subfolder, current_path) export_folder(pst_root, output_dir) finally: # 移除PST文件,避免Outlook残留配置 outlook.RemoveStore(pst_store) del outlook # 调用示例 export_pst_to_msg("PathTo.pst", "D:\\ExportedMessages")
注意事项:
- 运行代码时需确保Outlook已安装并正常运行
- 若遇到权限问题,需以管理员身份运行脚本
- 邮件主题中的非法字符会被替换,避免保存失败
内容的提问来源于stack exchange,提问作者Legion
相关产品推荐
相关产品推荐

