You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

python-docx提取Docx时丢失Delaware,求无需手动改文件的解决代码

解决python-docx无法提取文档中特定文本(如"Delaware")的问题

我之前也碰到过一模一样的情况——python-docx的paragraph.text会漏掉某些特殊格式的文本,原因正如你提到的相关内容所说:这个"Delaware"并不是普通的段落文本,而是被放在了内容控件、隐藏域或者其他特殊XML节点里,python-docx的上层API默认不会遍历这些节点来拼接文本。

下面是几个无需手动修改文档就能提取到该文本的解决方案,完全支持批量处理你的数千份文件:

方法1:直接从文档XML提取所有文本

docx本质是一个ZIP包,所有内容都存在word/document.xml里,我们可以直接解析这个XML的所有文本节点,绕过上层API的限制:

import docx
import io
import requests
from lxml import etree

url = 'https://github.com/python-openxml/python-docx/files/1996979/Delaware_Test.docx'
file = io.BytesIO(requests.get(url).content)

# 加载文档并获取XML根节点
doc = docx.Document(file)
root = doc._element.body

# 提取所有文本节点内容
full_text = ''.join(root.xpath('//text()'))
print(full_text)

这个方法会把文档里所有可见的文本都提取出来,不管它被放在什么格式容器里。

方法2:遍历段落的所有Run元素

有时候遗漏的文本会被放在单独的Run里,而paragraph.text可能因为Run的特殊属性(比如关联控件、隐藏格式标记)没有把它拼接进去,我们可以手动遍历每个段落的所有Run:

import docx
import io
import requests

url = 'https://github.com/python-openxml/python-docx/files/1996979/Delaware_Test.docx'
file = io.BytesIO(requests.get(url).content)

doc = docx.Document(file)
full_text = []

for para in doc.paragraphs:
    # 遍历段落里的每一个Run
    for run in para.runs:
        if run.text:  # 避免加入空文本
            full_text.append(run.text)

print(''.join(full_text))

方法3:专门处理内容控件(Content Control)

如果你的批量文档里大量使用内容控件来放置这类文本,可以针对性地提取内容控件内的文本:

import docx
import io
import requests

url = 'https://github.com/python-openxml/python-docx/files/1996979/Delaware_Test.docx'
file = io.BytesIO(requests.get(url).content)

doc = docx.Document(file)
root = doc._element.body

# 提取普通文本 + 内容控件内的文本
text_segments = root.xpath('//text() | //w:sdt//w:t/text()')
full_text = ''.join(text_segments)
print(full_text)

内容的提问来源于stack exchange,提问作者dshefman

火山引擎 最新活动