python批量提取word指定内容_利用python-docx批量处理Word文件—图片

图片是Word的一种特殊内容,这篇文章主要内容是如何利用python-docx批量提取Word中的图片,以及如何在Word国插入图片。

1.提取Word中的图片并保护成指定格式

docx好像并没有直接获取图片的方法,网上的资料也很少,有用的资料我就找到这一篇:

如何从pythondocx段中获取图像(Inlineshape)

说实话,这篇文章我看的不是太懂,而且这个方法只能获得内联的图片,什么是内联的图片呢,我也不知道,我只知道我们在word中直接插入的图片不属于这种,也就是这种方法并不能获得word中直接插入的图片,我用add_picture()插入一张图片,用该方法可以获得。受这篇文章的启发,我看了一下python-docx的源码,虽然没有看懂,但也得到一个用有的信息:python-docx会将wrod文件转换成Proxy Type(不敢翻译)格式进行处理。Proxy Type格式是什么样的呢,其实质是xml,不同的类型会被转成不同的Proxy Type,以Document为例,可以用document._element.xml查看被转换后的内容:

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3h0ZmdlMDkxNQ==,size_16,color_FFFFFF,t_70

这就是word内容转换成Proxy Type后的形式(大部分信息被我折叠了),我对xml研究不多,可以看出所有标签都是的形式,整个文档包含在标签中,每段以

开始,

结束 ,图片在docx中也是段落,因此我们过以通过遍历整个xml找到包含图片的段落,要通过遍历找到图片,图片所在的段落必须有其特殊之处,不然我们也无判断。下面是一幅图处的Proxy Type的内容:

可以看到图片信息包含在标签中,因此我们可以通过该标签写信图片段落。

document有一个part属性,part有一个related_parts属性,其定义如下:

@property

def related_parts(self):

"""

Dictionary mapping related parts by rId, so child objects can resolve

explicit relationships present in the part XML, e.g. sldIdLst to a

specific |Slide| instance.

"""

return self.rels.related_parts

再看rels.related_partsr的定义:

@property

def related_parts(self):

"""

dict mapping rIds to target parts for all the internal relationships

in the collection.

"""

return self._target_parts_by_rId

self.rels.related_parts是一个字典,这个字典可以通过rId映射对应的内容,恰好在图片对应的Proxy Type内容(imagedata标签)中发现了这个属性,

可以看到,这个图片对应rId是rId8,运行

doc.part.related_parts['rId9']

发现前没有报错,将其存储成图片后,惊喜出现了——这就是该图片的内容。

整理上面的思路,获得图片的过程分3步:

获得各段的Proxy Type对象,它是一个xml;

遍历该xml,如果pict键存在,该段是图片,继续遍历获得rId;

利用related_parts获得图片内容。

下面详述该过程:

1.1 获得各段对应的Proxy Type xml数据

proxy=[]

for p in doc.paragraphs:

proxy.append(p._element.xml)

1.2 遍历xml,找到图片所在的段落并获得rid

import xml.etree.cElementTree as ET

for p in proxy:

#一段一个根树

root=ET.fromstring(p)

#获得树,所有的树均是树的子树

pictr_str="%sr" % re.match('{\S+}',root.tag).group(0)

pictrs=root.findall(pictr_str)

pict_str="%spict" % re.match('{\S+}',root.tag).group(0)

picts=[]

rIds=[]

for pictr in pictrs:

#获得所有标签

pict=pictr.findall(pict_str)

#如果存在

if len(pict)>0:

picts.append(pict[0])

for pict in picts:

shape_str="%sshape" % re.match('{\S+}',pict[0].tag).group(0)

#获得标签

shape=pict.findall(shape_str)[0]

attrib=[]

#标签

imagedata=shape.findall("%simagedata" % re.match('{\S+}',pict[0].tag).group(0))

rIds.append(imagedata[0].attrib['{http://schemas.openxmlformats.org/officeDocument/2006/relationships}id'])

ps:这部分代码需要对照xml才能看懂。

1.3 获得image数据

imgs=[]

for rid in rIds:

imgs.append(doc.part.related_parts[rid])

1.4 保存图片到本地

i=1

for img in imgs:

f=open("img%d.jpg" % i,'wb')

f.write(img.blob)

f.close()

i+=1

2.给word插入图片

插入图片就比较简单了:

doc.add_picture('img_path',width=Cm(16),height=Cm(12))

后记:从word中读出图片在点复杂,这个代码肯定不能满足所有word文件,也可能存在很多问题,毕竟这个在官方API中并没有提到,我只是抛砖引玉,如果大家有更好的方法欢迎交流。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值