python - 如何使用 python-docx 读取源自 Word 模板的 docx?
问题描述
我正在使用python-docx库获取 docx 文件的所有文本。其简化代码如下
from docx import Document
def read_element(doc):
for p in doc.paragraphs:
print('paragraph text:', p.text)
for table in doc.tables:
for row in table.rows:
for cell in row.cells:
read_element(cell)
doc = Document("<path to file>")
read_element(doc)
这在许多情况下都非常有用,除非我从通过 Microsoft Word 模板生成的文件中读取。在这些情况下,它只读取我在文件中写入的输入,而不是模板附带的文本
复制
- 通过创建 Microsoft Word 文档
Create from template
- 在里面写一个字,即“测试”
- 保存
- 在上面的代码中替换它的路径
- 运行代码
输出:
paragraph text: testing
paragraph text: To learn more and get OneNote, visit .
当文件的文本多于输出内容时
做笔记测试
- 要记笔记,只需点按此处并开始输入。
- 或者,使用免费的 OneNote 应用程序,轻松地为您的所有笔记创建一个在您的设备上自动同步的数字笔记本。
要了解更多信息并获取 OneNote,请访问www.onenote.com。
正如我们在文件图像中看到的那样,我们正在尝试读取Docx 文件
关于如何检索丢失的文本的任何想法?
解决方案
python-docx
只会在文档的顶层找到段落和表格。特别是,不会检测到“包装”在“容器”元素中的段落或表格。
最常见的是,“容器”是一个待定(尚未接受)的修订版,这会产生类似的行为。
要提取“包装”文本,您需要知道“包装”元素是什么。一种方法是转储文档正文的 XML:
document = Document("my-document.docx")
print(document._body._body.xml)
段落元素有一个w:p
标签,您可以检查输出以查找那些,我希望其中一些将在另一个元素内。
然后您可以使用 XPath 表达式提取这些元素,如下所示,如果“包装器”元素为<w:x>
:
from docx.text.paragraph import Paragraph
body = document._body._body
ps_under_xs = body.xpath("w:x//w:p")
for p in ps_under_xs:
paragraph = Paragraph(p, None)
print(paragraph.text)
您也可以只获取<w:p>
文档中的所有元素,而不考虑它们的“亲子关系”,如下所示:
ps = body.xpath(".//w:p")
这样做的缺点是某些容器(例如未接受的修订标记)可能包含已从文档中“删除”的文本,因此您可能会得到比您想要的更多的内容。
无论如何,这种通用方法应该适用于您所描述的工作。如果您需要更复杂的内容,可以在搜索中找到有关 XPath 表达式的更多信息。
推荐阅读
- docker - 用于 docker 安装的 Wsl 更新
- tsql - 为什么在完全隔离的情况下@@rowcount 等于 1?
- opengl - OpenGL - 修改纹理参数
- python - (PyQT)当许多元素连接到回调函数时,如何获取哪个元素触发了回调函数?
- c++ - 从派生类访问成员函数的基类指针向量?正确的方法?
- loops - ReadString 读取 EOF 时如何中断循环?
- python - NLTK 不能在带有 KivyMD 的 Android Buildozer 应用程序中工作
- assembly - 具有两个大小为 10 的整数数组 X 和 Y 的汇编程序,其中 Y 包含:如果 X 中的元素为正,则为 1,如果该元素 < = 0,则为 0
- groovy - Groovy,检查数组中的所有元素是否包含子字符串
- python - 如果您之前没有连接到 wifi,如何通过 linux 或 Windows 上的 python 连接到 wifi。(输入:SSID、密码)