1

还在学习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

谢谢你的帮助。

法比奥

4

1 回答 1

0

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

  1. findall您需要在使用命名空间参数时定义命名空间前缀。然后你的 xpath 必须包含前缀。
  2. 使用findall时不要包括根,因为那是起点,而是从其子节点向下。
  3. 没有带复数的Bags本地名称,但只有Bag,其长度为一。如果你想要它的孩子,那就更深一层。

考虑调整后的脚本:

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
于 2017-03-20T00:16:44.700 回答