使用python

时间:2017-03-19 21:19:02

标签: python xml image metafile

还在学习python。我目前正在研究一个python代码,它将从图像中提取元数据(用户自制的关键字)。 我已经尝试了Pillow AND exif,但这不包括用户制作的标签或关键字。 使用applist,我成功地设法提取包含我的关键字的图元文件,但是当我尝试用ElementTree解包它以提取感兴趣的部分时,我只获得空数据。

我的xml文件看起来像这样(经过一些操作):

<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="XMP Core 4.4.0">
   <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
      <rdf:Description rdf:about=""
            xmlns:dc="http://purl.org/dc/elements/1.1/">
         <dc:description>
            <rdf:Seq>
               <rdf:li xml:lang="x-default">South Carolina, Olivyana, Kumasi</rdf:li>
            </rdf:Seq>
         </dc:description>
         <dc:subject>
            <rdf:Bag>
               <rdf:li>Kumasi</rdf:li>
               <rdf:li>Summer 2016</rdf:li>
               <rdf:li>Charlestone</rdf:li>
               <rdf:li>SC</rdf:li>
               <rdf:li>Beach</rdf:li>
               <rdf:li>Olivjana</rdf:li>
            </rdf:Bag>
         </dc:subject>
         <dc:title>
            <rdf:Seq>
               <rdf:li xml:lang="x-default">P1050365</rdf:li>
            </rdf:Seq>
         </dc:title>
      </rdf:Description>
      <rdf:Description rdf:about=""
            xmlns:aux="http://ns.adobe.com/exif/1.0/aux/">
         <aux:SerialNumber>F360908190331</aux:SerialNumber>
      </rdf:Description>
   </rdf:RDF>
</x:xmpmeta>

我的代码如下所示:

import xml.etree.ElementTree as ET
from PIL import Image, ExifTags
with Image.open("myfile.jpg") as im:
    for segment, content in im.applist:
        marker, body = content.split(b'\x00', 1)
        if segment == 'APP1' and marker == b'http://ns.adobe.com/xap/1.0/':
            data = body.decode('"utf-8"')
print (data)

此时无法将此传递给解析器,因为返回错误的空行:

tree = ET.parse(data)

ValueError: embedded null byte

所以在删除之后我将数据保存在xml文件中(上面的xml数据)并传递给解析器,但没有获取数据:

tree = ET.parse('mytags.xml')
tags = tree.findall('xmpmeta/RDF/Description/subject/Bags')
print (type(tags))
print (len(tags))

<class 'list'>
0

有趣的是,我使用了xml文件形式的标签(即'x:xmpmeta':),我收到以下错误:

SyntaxError: prefix 'x' not found in prefix map

感谢您的帮助。

的Fabio

1 个答案:

答案 0 :(得分:0)

只关注XML解析而不是PIL元数据工作,问题就在于三个问题:

  1. 使用findall时,您需要定义名称空间前缀,您可以使用名称空间 arg。然后你的xpath必须包含前缀。
  2. 使用findall时,请不要包含根,因为它是起点,但是从子节点开始。
  3. 没有带有复数的 Bags 本地名称,但只有 Bag ,其长度为1。如果你想要它的孩子,那就更深一层了。
  4. 考虑调整后的脚本:

    import xml.etree.ElementTree as ET
    
    tree = ET.parse('mytags.xml')
    
    nmspdict = {'x':'adobe:ns:meta/',            
                'rdf': 'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
                'dc': 'http://purl.org/dc/elements/1.1/'}
    
    tags = tree.findall('rdf:RDF/rdf:Description/dc:subject/rdf:Bag/rdf:li',
                        namespaces = nmspdict)
    
    print (type(tags))
    print (len(tags))
    
    # <class 'list'>
    # 6
    
    for i in tags:
        print(i.text)
    # Kumasi
    # Summer 2016
    # Charlestone
    # SC
    # Beach
    # Olivjana