不能直接用 open() 读取 .docx 文件,因为 .docx 是 ZIP 压缩包,内含 XML 结构,直接 open() 会因读取二进制流导致 UnicodeDecodeError;必须用 python-docx 等支持 Office Open XML 的库解析。

用 python-docx 读取 Word 内容再写入 .txt 是最稳妥的方案,win32com 或系统命令(如 soffice)虽能用,但依赖环境、不可跨平台、易卡死,不推荐作为批量主力。
为什么不能直接用 open() 读取 .docx 文件?
.docx 是 ZIP 压缩包,里面包含 XML 结构文件,直接 open() 只会读到二进制乱码或报错 UnicodeDecodeError: 'utf-8' codec can't decode byte。必须用能解析 Office Open XML 格式的库。
常见错误现象:
- 用
with open("a.docx") as f: f.read()→ 报UnicodeDecodeError - 误以为
codecs.open(..., encoding="gbk")能解决 → 实际仍是无效字节流
用 python-docx 提取正文文本(不含表格、页眉页脚)
它专注读取段落(Paragraph)和运行(Run),适合纯文本导出场景。注意:不处理公式、文本框、批注,也不保留格式(如加粗/斜体仅剩文字)。
立即学习“Python免费学习笔记(深入)”;
华为云 Python SDK 查询工具。自动发现已安装 SDK 的服务包、Client类、API 方法、入参详情、类信息(__init__ 参数、属性、类型、描述),支持关键字搜索,快速定位目标 API 使用方法。
实操建议:
- 安装:
pip install python-docx - 只遍历
document.paragraphs,跳过document.sections和document.tables(除非你明确要处理表格) - 每段末尾手动加
\n,否则所有段落会连成一行 - 用
.text.strip()清理首尾空格和空行,避免生成大量空白行
示例片段:
from docx import Document
<p>def docx_to_text(docx_path):
doc = Document(docx_path)
lines = []
for p in doc.paragraphs:
if p.text.strip(): # 跳过纯空白段
lines.append(p.text.strip())
return "\n".join(lines)</p><p>text = docx_to_text("input.docx")
with open("output.txt", "w", encoding="utf-8") as f:
f.write(text)
批量转换时要注意编码、路径和异常隔离
批量场景下,单个文件出错(如损坏、加密、权限不足)不该中断整个流程。同时 Windows 路径含中文、空格,Linux/macOS 可能有大小写敏感问题,都得提前兜住。
关键点:
- 用
pathlib.Path处理路径,比字符串拼接更安全;.stem获取无后缀文件名,.with_suffix(".txt")生成目标路径 - 输出统一用
encoding="utf-8",避免 Windows 记事本乱码;不要用encoding="gbk"—— 它无法兼容含 emoji 或生僻字的原文 - 每个文件用
try/except包裹,捕获PermissionError、KeyError(文档结构异常)、ValueError(加密文档)等,并记录日志 - 跳过非
.docx文件(如~$xxx.docx临时文件),用path.suffix.lower() == ".docx"判断
真正麻烦的是带密码保护的文档或旧版 .doc(OLE 格式)——python-docx 完全不支持。这类必须单独识别并跳过,或者改用 antiword(Linux)或调用系统 Word(Windows + win32com),但后者意味着放弃自动化稳定性。

















