使用Python+BeautifulSoup将img标签替换为对应OCR识别文本
Tika解析docx替换img为OCR文本实现方案
实现逻辑
- 优先构建OCR内容映射表:遍历XML内所有
name="resourceName"的<meta>标签,提取标签content属性存的图片文件名,同时找到该标签所属解析块内class="ocr"的div标签,提取识别到的文本,以键值对形式存入字典,后续替换直接查表即可,无需重复遍历DOM,效率更高 - 处理img标签src前缀:Tika输出的img标签src值默认带
embedded:前缀,匹配前需要先剥离该前缀,才能和映射表内的文件名精准匹配 - 原位替换img节点:遍历正文所有
<img>标签,匹配到对应OCR文本后,直接在原img标签的位置插入文本节点,保证文本顺序和原文档排版一致
可直接运行的代码示例
from bs4 import BeautifulSoup, NavigableString # 读取Tika输出的XML内容,替换为你自己的文件读取/接口返回逻辑 with open("tika_result.xml", "r", encoding="utf-8") as f: tika_xml_content = f.read() # 初始化BeautifulSoup对象,用xml解析器避免标签属性解析异常 soup = BeautifulSoup(tika_xml_content, "xml") # 第一步:构建 图片文件名->OCR文本 的映射字典 ocr_content_map = {} for resource_meta in soup.find_all("meta", attrs={"name": "resourceName"}): img_file_name = resource_meta.get("content") if not img_file_name: continue # meta标签的父节点即为单张图片对应的解析块 img_parse_block = resource_meta.parent ocr_div = img_parse_block.find("div", attrs={"class": "ocr"}) if ocr_div: # 提取OCR文本,可根据需求决定是否strip前后空白 ocr_content_map[img_file_name] = ocr_div.get_text(strip=True) # 第二步:遍历所有img标签做替换 for img_tag in soup.find_all("img"): img_src = img_tag.get("src", "") # 剥离embedded:前缀 if img_src.startswith("embedded:"): real_file_name = img_src.split("embedded:", 1)[1] # 查到对应OCR内容就替换 if real_file_name in ocr_content_map: img_tag.replace_with(NavigableString(ocr_content_map[real_file_name])) # 最终提取处理完成的全文档文本 final_doc_text = soup.get_text()
适配说明
- 如果你的Tika输出XML中,resourceName对应的meta标签和ocr div不在同一个直接父节点下,只需要调整
img_parse_block的查找逻辑(比如改成找向上3层父节点)即可,核心匹配逻辑不需要改动 - 常规docx经Tika解析生成的embedded前缀文件名都是唯一的,如果遇到重名图片导致匹配错误,可以给映射表的key补充上层路径等唯一标识做区分
- 替换逻辑默认保留原文档的内容顺序,OCR文本会插入到原图片所在的正文位置,不需要额外做顺序调整
内容的提问来源于stack exchange,提问作者Tau n Ro
相关产品推荐
相关产品推荐

