关于使用python解析docx

最近工作涉及到解析docx,看了许多方法,用C++,java,python都有,最后发现实用性包括简易性还是得python,根本跑不了。然后又看了许多python解析docx的库,最终选择使用python-docx。当然,其实很多教程也是关于如何使用python-docx进行word文档解析的,但是如果我们使用python-docx的基本功能,如:

段落打印:

from docx import Document
from docx.shared import Inches

document = Document('demo.docx')  #打开文件
for paragraph in document.paragraphs:
    print(paragraph.text)  #打印各段落内容文本

或是表格提取:

import docx
from docx import Document #导入库

path = 'demo.docx' #文件路径
document = Document(path) #读入文件
tables = document.tables #获取文件中的表格集

for table in tables[:]:
    for i, row in enumerate(table.rows[:]):   # 读每行
        row_content = []
        for cell in row.cells[:]:  # 读一行中的所有单元格
            c = cell.text
            row_content.append(c)
        print (row_content) #以列表形式导出每一行数据

利用这种方式进行读取,我们只能读取每部分的最基本的文字信息,对于一些特殊字符无法进行读取及解析。

如:之类的符号,无法通过这种方式解析出来,但是又很需要,这时候就需要我们换一个思路,使用OPENXML进行word的解析。

其实想了解openxml,只要将docx文件后缀改为zip然后解压缩就会发现,整个文件其实分成了很多xml文件,分别存储了文档的内容,格式,打开document.xml就会看到我们的正文内容了。

其中document.xml也遵循了xml的数据结构,包含标签,属性啥的。所以我们要做的就是将表示特殊符号的标签找到,将它恢复到原文中的对应位置。

所以这里选择python-docx的原因就是,他可以在读取docx的同时恢复他的openxml结构,我们可以直接利用xml的方式进行标签搜索。

首先我们先了解一下openxml的格式,参考https://blog.csdn.net/liuqixuan1994/article/details/104486600/

整体结构:body、styles、setting等

段落Paragraph结点:<w:p>

基本格式单位Run结点:<w:r>

格式Properties结点:<w:pPr><w:rPr>

字体<w:rFonts>

字号<w:sz><w:szCs>

看的见的文字Text:<w:t>

其中我们需要分析特殊字符在xml文件中的表示方法,我碰到的大概三种,一种是

基于这个原因,我们可以在xml中直接搜索对应的标签去寻找特殊字符。

首先我们读取文档,并以XML的方式打开,找到w:r标签,基本段落单元:

from docx import Document
from lxml import etree

doc = Document('demo.docx')
body_xml_str = doc._body._element.xml # 获取body中的xml
body_xml = etree.fromstring(body_xml_str) # 转换成lxml结点
print(etree.tounicode(body_xml)) # 打印查看

for p in doc.paragraphs:
    p_xml_str = p._p.xml # 按段落获取xml
    p_xml = etree.fromstring(p_xml_str) # 转换成lxml结点
    print(etree.tounicode(p_xml)) # 打印查看
    xml_dom = parseString(etree.tounicode(p_xml))
    stus = xml_dom.getElementsByTagName('w:r')
    for si in stus:
        print(si)

提取段落中的特殊字符:

sym_id = si.getElementsByTagName('w:sym')
    for sym_i in sym_id:
        if((sym_i.attributes._attrs['w:font'].nodeValue=='Wingdings2')and(sym_i.attributes._attrs['w:char'].nodeValue=='0052')):
            print('特殊字符',end='')
    
sym_box = si.getElementsByTagName('w:instrText')
for box_i in sym_box:
    if((box_i.childNodes[0].data == 'FORMCHECKBOX'):
        print('特殊字符',end='')

sym_box = si.getElementsByTagName('w:checked')
for box_i in sym_box:
    print('特殊字符',end='')

这样就可以将特殊字符找到了,当然具体场景还得具体去找对应的表示方式进行具体匹配。

  • 4
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值