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

Python开发邮件服务器重写URL时多部分HTML邮件重构问题

解决Python email模块处理多部分邮件的内容修改问题

核心问题原因说明

  • msg.walk()会递归遍历所有层级的part,包含multipart类型的容器part,如果不加过滤直接处理,就会出现内容重复遍历的问题
  • 不需要手动重构邮件结构,直接修改对应子part的内容即可自动保留原有邮件结构(包括附件、headers、嵌套层级等)

可直接使用的实现代码

import re
from email import policy
from email.parser import BytesParser

# 加载需要替换的URL映射,可自行修改为读取文本文件的逻辑
url_replace_map = {
    "https://old-domain.com/link1": "https://new-domain.com/rewrite1",
    "https://old-domain.com/link2": "https://new-domain.com/rewrite2"
}

def replace_url_in_content(content, replace_map):
    # 替换逻辑示例,可根据自身需求调整匹配规则
    for old_url, new_url in replace_map.items():
        content = content.replace(old_url, new_url)
    # 如需正则匹配替换可使用下面的逻辑
    # content = re.sub(r'https://old-domain\.com/(\w+)', r'https://new-domain.com/rewrite/\1', content)
    return content

def process_email(raw_email_bytes):
    # 用默认policy解析邮件,保证保留所有结构信息
    msg = BytesParser(policy=policy.default).parsebytes(raw_email_bytes)
    
    # 遍历所有part,跳过multipart容器只处理内容part
    for part in msg.walk():
        # 跳过multipart类型的容器part,避免重复处理
        if part.is_multipart():
            continue
        content_type = part.get_content_type()
        # 只处理纯文本和HTML正文,跳过附件等其他类型内容
        if content_type not in ('text/plain', 'text/html'):
            continue
        # 读取原内容
        original_content = part.get_content()
        # 替换URL
        modified_content = replace_url_in_content(original_content, url_replace_map)
        # 把修改后的内容写回part,自动保留原有编码、content-type等属性
        part.set_content(modified_content, subtype=part.get_content_subtype(), charset=part.get_content_charset())
    
    # 直接返回修改后的完整邮件字节流,原有结构完全保留
    return bytes(msg)

# 使用示例
if __name__ == "__main__":
    # 读取原始邮件文件
    with open("original.eml", "rb") as f:
        raw_email = f.read()
    modified_email = process_email(raw_email)
    # 保存修改后的邮件
    with open("modified.eml", "wb") as f:
        f.write(modified_email)

原有代码问题修正

  1. 不需要单独判断非多部分邮件分支,上述遍历逻辑对单部分和多部分邮件都通用
  2. 不要新建newmsg对象替换原邮件,直接修改原msg的子part即可,所有原有头部信息、附件、嵌套结构都会完整保留
  3. 遍历walk()时增加if part.is_multipart(): continue的判断即可解决子内容重复出现的问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 16:54:01