Python如何遍历MIME消息树并获取其精确层级图结构(如邻接矩阵)
Python获取MIME消息精确层级结构的方法
Python标准库的email模块完全支持获取MIME消息的精确层级结构,email.walk()属于无层级信息的深度优先遍历,我们只要自行递归处理消息载荷即可记录完整的父子节点关系,还可进一步生成邻接矩阵形式的图结构。
核心原理
MIME消息本身是典型的树形结构:
- 当消息部分的
is_multipart()返回True,或者类型为message/*时,调用get_payload()会返回嵌套的子消息列表 - 普通类型(如
text/plain、image/png)的消息部分是叶子节点,没有子节点
示例1:递归打印带层级的MIME结构
from email import policy from email.parser import BytesParser def print_mime_structure(part, level=0): indent = " " * level print(f"{indent}{part.get_content_type()}") # 遍历子节点 if part.is_multipart() or part.get_content_maintype() == 'message': for sub_part in part.get_payload(): print_mime_structure(sub_part, level + 1) # 读取解析MIME消息示例 with open("test.eml", "rb") as f: msg = BytesParser(policy=policy.default).parse(f) print_mime_structure(msg)
运行上述代码即可输出带缩进的层级结构,直接区分你提到的两种不同嵌套场景。
示例2:生成邻接矩阵形式的图结构
我们可以给每个节点分配唯一ID,遍历过程中记录父子关联,最终生成邻接矩阵:
def build_mime_adj_matrix(part): nodes = [] edges = [] # 递归给节点分配ID,记录边 def traverse(node, parent_id=-1): node_id = len(nodes) nodes.append(node.get_content_type()) if parent_id != -1: edges.append((parent_id, node_id)) if node.is_multipart() or node.get_content_maintype() == 'message': for sub_node in node.get_payload(): traverse(sub_node, node_id) traverse(part) # 生成邻接矩阵 n = len(nodes) adj_matrix = [[0]*n for _ in range(n)] for u, v in edges: adj_matrix[u][v] = 1 return nodes, adj_matrix # 调用示例 nodes, adj_matrix = build_mime_adj_matrix(msg) print("节点类型列表:", nodes) print("邻接矩阵:") for row in adj_matrix: print(row)
邻接矩阵中adj_matrix[u][v] = 1代表ID为u的节点是ID为v的节点的父节点。
内容的提问来源于stack exchange,提问作者Konov Mike
相关产品推荐
相关产品推荐

