Извлекать ключевые слова из изображений с помощью Python

Все еще изучаю питон. В настоящее время я работаю над кодом Python, который извлекает метаданные (пользовательские ключевые слова) из изображений. Я уже пробовал Подушку И 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 ответ

Сосредоточившись только на анализе XML, а не на работе метаданных PIL, ваша проблема состоит в трех проблемах:

  1. Вам нужно определить префиксы пространства имен при использовании findall что вы можете сделать с пространствами имен Арг. И тогда ваш xpath должен включать префиксы.
  2. Когда используешь findall не включайте корень, поскольку это является отправной точкой, но от его дочернего элемента вниз.
  3. Нет никакого местного названия Сумки с множественным числом, но только Сумка и ее длина была бы одна. Если вы хотите, чтобы его дети, пойти на один уровень глубже.

Рассмотрим скорректированный скрипт:

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
Другие вопросы по тегам