import osimport reimport emailimport datetimefrom email.policy import defaultfrom pathlib import Path# ===================== 请修改这里为你的 EML 文件所在目录 =====================EML_FOLDER = r"D:\邮件备份\eml文件"# ==========================================================================def sanitize_filename(name: str) -> str:"""清理文件名/文件夹名,移除非法字符,防止创建失败"""invalid_chars = r'[\\/:*?"<>|]'return re.sub(invalid_chars, '', name).strip()def parse_sender(sender_str: str) -> str:"""解析发件人,优先提取名称,无名称则返回邮箱地址"""sender_str = sender_str.strip() match = re.search(r'(.*?)\s*<([^<>]+)>', sender_str)if match: name = match.group(1).strip('"').strip()return name if name else match.group(2)return sender_strdef parse_date(msg) -> str:"""解析邮件发送时间,统一格式:2025-12-29 1430"""date_tuple = msg.get('Date')if not date_tuple:return "未知时间"try: date_obj = email.utils.parsedate_to_datetime(date_tuple)return date_obj.strftime("%Y-%m-%d %H%M")except:return "时间解析失败"def process_one_eml(eml_path: Path):"""处理单个eml文件:解析信息 → 创建文件夹 → 保存附件"""try:with open(eml_path, 'rb') as f: msg = email.message_from_bytes(f.read(), policy=default)# 1 解析邮件核心信息sender = parse_sender(msg.get('From', '未知发件人')) date_str = parse_date(msg) subject = sanitize_filename(msg.get('Subject', '无标题'))# 2 拼接文件夹名称:时间 + 发件人 + 标题folder_name = f"{date_str} {sender} {subject}"save_folder = Path(EML_FOLDER) / folder_name save_folder.mkdir(exist_ok=True)# 3 提取并保存所有附件attachment_count = 0for part in msg.walk():if part.get_content_disposition() == 'attachment': filename = part.get_filename()if not filename:continue# 清理附件名,避免非法字符filename = sanitize_filename(filename) save_path = save_folder / filename# 写入附件with open(save_path, 'wb') as f: f.write(part.get_payload(decode=True)) attachment_count += 1print(f"✅ 处理完成:{eml_path.name} | 附件数:{attachment_count} | 保存至:{folder_name}")except Exception as e: print(f"❌ 处理失败:{eml_path.name},错误:{str(e)}")def batch_process_eml():"""批量处理目录下所有eml文件"""folder = Path(EML_FOLDER)if not folder.exists(): print(f"目录不存在:{EML_FOLDER}")returneml_files = list(folder.glob("*.eml"))if not eml_files: print("未找到任何 .eml 文件")returnprint(f"共找到 {len(eml_files)} 个eml文件,开始处理...\n")for eml in eml_files: process_one_eml(eml) print("\n🎉 全部处理完成!")if __name__ == "__main__": batch_process_eml() |