如何按原文档顺序提取Word文档中的文本、表格及图片地址?
如何按原文档顺序提取Word文档中的文本、表格及图片地址?
嘿,我明白你现在的痛点了——单独遍历doc.element.body拿不到图片,只循环doc.part.rels.values又丢了文本和表格的顺序,确实头疼!其实我们可以通过遍历文档的所有块级元素+关联关系映射的方式,完美保留原文档的顺序来提取所有内容。下面给你具体的解决方案:
核心思路
Word文档的内容是按「块级元素」顺序排列的(段落、表格、内嵌图片都属于这个流),我们可以先提前建立图片关系ID(rId)到地址的映射,再按顺序遍历所有块元素,分别处理文本、表格和内嵌图片,这样就能保证内容顺序和原文档完全一致。
具体实现代码(以python-docx为例)
首先确保你已经安装了python-docx库:
pip install python-docx
然后用以下代码提取内容:
from docx import Document def extract_doc_content(doc_path): # 加载文档 doc = Document(doc_path) # 提前建立「关系ID -> 图片地址」的映射,避免重复遍历rels image_rels_map = { rel.rId: rel.target_ref for rel in doc.part.rels.values() if "image" in rel.target_ref.lower() } extracted_content = [] # 按顺序遍历文档body中的所有元素 for element in doc.element.body.iter(): # 处理段落元素(包含文本和内嵌图片) if element.tag.endswith("p"): # 把xml元素转换成docx的Paragraph对象 paragraph = doc._body._element_to_object(element) # 提取段落文本 para_text = paragraph.text.strip() if para_text: extracted_content.append(f"📝 文本内容: {para_text}") # 提取段落中的内嵌图片 for run in paragraph.runs: # 通过XPath定位内嵌图片的关系ID inline_images = run._element.xpath(".//w:drawing//wp:inline") for img in inline_images: r_id = img.xpath(".//a:blip/@r:embed")[0] if r_id in image_rels_map: extracted_content.append(f"🖼️ 图片地址: {image_rels_map[r_id]}") # 处理表格元素 elif element.tag.endswith("tbl"): # 把xml元素转换成docx的Table对象 table = doc._body._element_to_object(element) extracted_content.append("--- 表格开始 ---") # 逐行提取表格内容 for row in table.rows: cell_contents = [cell.text.strip() for cell in row.cells] extracted_content.append(" | ".join(cell_contents)) extracted_content.append("--- 表格结束 ---") return extracted_content # 使用示例 if __name__ == "__main__": content_list = extract_doc_content("你的文档路径.docx") for item in content_list: print(item)
代码说明
- 图片映射预处理:先遍历文档的关系集合(rels),把所有图片的rId和对应的内部地址存成字典,后续找图片地址时直接查字典,效率更高。
- 按顺序遍历块元素:
doc.element.body.iter()会严格按照原文档的顺序遍历所有块级元素,确保内容顺序不混乱。 - 分类型处理内容:
- 段落:先提取文本,再遍历段落中的每个run,通过XPath找到内嵌图片的rId,再从映射字典中获取图片地址。
- 表格:标记表格的开始/结束,逐行逐单元格提取文本,用
|分隔单元格内容,方便区分表格结构。
额外注意事项
- 如果文档中有浮动式图片(不是内嵌在段落里的),这类图片不会出现在段落的run中,你可以额外遍历
doc.shapes来处理,但浮动图片的位置和文本流的对应关系需要额外判断,一般内嵌图片的顺序更贴合文本流。 - 代码中获取的图片地址是docx压缩包内的相对路径,如果需要导出图片文件,可以通过
doc.part.rels[r_id].target_part.blob获取图片的二进制内容,再保存为本地文件。
备注:内容来源于stack exchange,提问作者user30342609




