如何使用 python-docx 从现有 docx 文件中提取文本
- 2025-03-07 08:59:00
- admin 原创
- 29
问题描述:
我正在尝试使用python-docx
模块(pip install python-docx
),但它似乎非常令人困惑,因为在github repo测试示例中他们使用的是opendocx
函数,但在readthedocs中他们使用的Document
是类。即使他们只展示了如何将文本添加到 docx 文件,而不是读取现有文件?
第一个 ( opendocx
) 不起作用,可能已被弃用。对于第二种情况,我尝试使用:
from docx import Document
document = Document('test_doc.docx')
print(document.paragraphs)
它返回了一个列表<docx.text.Paragraph object at 0x... >
然后我做了:
for p in document.paragraphs:
print(p.text)
它返回了所有文本,但缺少了一些内容。控制台上的文本中不存在所有 URL(按 CTRL+CLICK 转到 URL)。
问题是什么?为什么 URL 丢失了?
我怎样才能在不迭代循环的情况下获得完整的文本(例如open().read()
)
解决方案 1:
你可以尝试这个
import docx
def getText(filename):
doc = docx.Document(filename)
fullText = []
for para in doc.paragraphs:
fullText.append(para.text)
return '
'.join(fullText)
解决方案 2:
您可以使用python-docx2txt,它改编自 python-docx,但也可以从链接、页眉和页脚中提取文本。它还可以提取图像。
解决方案 3:
无需安装python-docx
docx
基本上是一个 zip 文件,其中包含多个文件夹和文件。在下面的链接中,您可以找到一个简单的函数来从docx
文件中提取文本,而无需依赖后者python-docx
,lxml
后者有时很难安装:
http://etienned.github.io/posts/extract-text-from-word-docx-simply/
解决方案 4:
python-docx 有两“代”。初始代以 0.2.x 版本结束,“新”代从 v0.3.0 开始。新代是对旧版本的全新、面向对象的重写。它有一个独特的存储库,位于此处。
opendocx() 函数是旧版 API 的一部分。文档适用于新版本。旧版没有任何文档可言。
当前版本不支持读取或写入超链接。该功能已列入规划,项目正在积极开发中。由于 Word 具有如此多的功能,因此它是一个非常广泛的 API。所以我们会开始实现它,但可能不会在下个月实现,除非有人决定专注于这方面并做出贡献。 更新此答案之后添加了超链接支持。
解决方案 5:
使用 python-docx,如@Chinmoy Panda 的答案所示:
for para in doc.paragraphs:
fullText.append(para.text)
但是,para.text
会丢失中的文本w:smarttag
(对应的 github 问题在这里:https://github.com/python-openxml/python-docx/issues/328),您应该使用以下函数:
def para2text(p):
rs = p._element.xpath('.//w:t')
return u" ".join([r.text for r in rs])
解决方案 6:
似乎这个问题没有官方的解决方案,但是这里发布了一个解决方法
https://github.com/savoirfairelinux/python-docx/commit/afd9fef6b2636c196761e5ed34eb05908e582649
只需更新此文件“...\site-packages\docx\oxml_ init _.py”
# add
import re
import sys
# add
def remove_hyperlink_tags(xml):
if (sys.version_info > (3, 0)):
xml = xml.decode('utf-8')
xml = xml.replace('</w:hyperlink>', '')
xml = re.sub('<w:hyperlink[^>]*>', '', xml)
if (sys.version_info > (3, 0)):
xml = xml.encode('utf-8')
return xml
# update
def parse_xml(xml):
"""
Return root lxml element obtained by parsing XML character string in
*xml*, which can be either a Python 2.x string or unicode. The custom
parser is used, so custom element classes are produced for elements in
*xml* that have them.
"""
root_element = etree.fromstring(remove_hyperlink_tags(xml), oxml_parser)
return root_element
当然,不要忘记在文档中提到我们正在改变官方库