docx文件本质是zip压缩包,需解压后解析word/document.xml中的w:t节点提取纯文本,注意命名空间、编码兼容性及干扰结构过滤。

DOCX 文件本质是 ZIP 压缩包,内部包含多个 XML 文件;直接解析 document.xml 是提取正文数据最可靠的方式,而非用 Office 自动化或第三方库“黑盒”读取。
定位并解压 document.xml
DOCX 文件不是二进制文档,而是符合 OPC(Open Packaging Conventions)的 ZIP 包。你需要先解压,再读取核心内容文件:
- 重命名
.docx为.zip,手动解压,或用命令行:unzip report.docx -d docx_unzipped
- 正文 XML 固定位于
word/document.xml(注意路径大小写敏感) - 不要依赖
document2.xml或header1.xml——那些是页眉/脚注/修订等辅助内容,非主文本流 - 若遇到加密或受保护文档(如启用“限制编辑”),
document.xml可能被移除或替换为占位符,此时需先检查_rels/.rels和word/_rels/document.xml.rels是否存在有效关系引用
解析 w:t 文本节点而非整段 w:p
Word 的 XML 使用 w: 命名空间,段落(w:p)内嵌套运行(w:r),真正文字在 w:t 中。直接取 w:p 的 textContent 会混入换行符、空格、制表符甚至隐藏字符(如
)。
- 用支持命名空间的解析器(如 Python 的
xml.etree.ElementTree需注册{http://schemas.openxmlformats.org/wordprocessingml/2006/main}前缀) - 只提取
w:t元素的.text属性值,跳过w:tab、w:br、w:cr等控制节点 -
w:t可能为空(<t></t>),需过滤None或空字符串 - 示例片段:
<w:p><w:r><w:t>Hello</w:t></w:r><w:r><w:t xml:space="preserve"> world</w:t></w:r></w:p>
对应文本是"Hello world",中间空格来自xml:space="preserve"属性
处理常见干扰结构:超链接、内嵌字段、样式标记
document.xml 中的文字可能被包裹在超链接(w:hyperlink)、域代码(w:fldChar + w:instrText)或带格式的 w:rPr 下,但这些不影响纯文本提取逻辑:
- 超链接文本仍在
w:t内,无需特殊处理;忽略w:hyperlink父节点即可 - 域字段(如页码、日期、TOC 条目)通常由
w:fldChar w:fldCharType="begin"+w:instrText+w:fldChar w:fldCharType="end"构成,其中w:instrText不是用户可见文本,应跳过 -
w:rPr(运行属性)只定义加粗/颜色/字体等,不携带文本,可安全忽略 - 若需保留段落结构(如区分标题与正文),应基于
w:pPr/w:pStyle中的val属性判断样式名(如"Heading1"),而非依赖字体大小或加粗
编码与特殊字符:别硬解 utf-8 就完事
XML 声明中指定的编码(如 <?xml version="1.0" encoding="UTF-8"?>)不一定被严格遵守;Word 生成的 DOCX 常含 Windows-1252 编码的遗留字符(如弯引号、破折号),或直接用 Unicode 字符实体(“)。
- 用
xml.etree.ElementTree.parse()(Python)或DOMParser(JS)解析,它们自动处理声明编码和实体解码 - 避免用
open(..., encoding="utf-8")直接读取后手动解析字符串——会因 BOM、混合编码失败 - 遇到
UnicodeDecodeError,先检查文件是否被其他程序(如 Word Online)保存为非标准 ZIP 格式(如含非 ASCII 文件名未按 UTF-8 编码),此时需用zipfile.ZipFile的strict_timestamps=False或降级到bytes模式读取
最易被忽略的是:不同 Word 版本生成的 document.xml 可能含扩展命名空间(如 w14:, w15:),但只要不解析其内容,标准 w: 节点结构始终稳定;一旦开始依赖 w:bookmarkStart 或 w:commentRangeStart 等高级结构,就必须校验目标 DOCX 的 [Content_Types].xml 是否声明了对应 schema。










