Как использовать Xpath в Python?

195

Что такое библиотека? Есть ли полная реализация? Как используется библиотека? Где находится его веб-сайт?

  • 2
    У меня есть это подлое подозрение, что ответы на этот вопрос сейчас немного устарели.
  • 4
    Ответ @ gringo-suave выглядит как хорошее обновление. stackoverflow.com/a/13504511/1450294
Теги:
xpath
dom
nodes

10 ответов

106

libxml2 имеет ряд преимуществ:

  • Соответствие spec
  • Активная разработка и участие сообщества
  • Скорость. Это действительно оболочка python вокруг реализации C.
  • Ubiquity. Библиотека libxml2 широко распространена и, таким образом, хорошо протестирована.

Недостатки включают:

  • Соответствие spec. Это строго. Такие вещи, как обработка имен по умолчанию, проще в других библиотеках.
  • Использование собственного кода. Это может быть болью в зависимости от того, как ваше приложение распространяется/развертывается. Доступны RPM, которые облегчают часть этой боли.
  • Ручная обработка ресурсов. Обратите внимание на пример ниже вызовов freeDoc() и xpathFreeContext(). Это не очень Pythonic.

Если вы делаете простой выбор пути, придерживайтесь ElementTree (который включен в Python 2.5). Если вам нужна полная спецификация соответствия или необработанная скорость и вы можете справиться с распространением собственного кода, перейдите к libxml2.

Пример использования libxml2 XPath


import libxml2

doc = libxml2.parseFile("tst.xml")
ctxt = doc.xpathNewContext()
res = ctxt.xpathEval("//*")
if len(res) != 2:
    print "xpath query: wrong node set size"
    sys.exit(1)
if res[0].name != "doc" or res[1].name != "foo":
    print "xpath query: wrong node set value"
    sys.exit(1)
doc.freeDoc()
ctxt.xpathFreeContext()

Пример использования ElementTree XPath


from elementtree.ElementTree import ElementTree
mydoc = ElementTree(file='tst.xml')
for e in mydoc.findall('/foo/bar'):
    print e.get('title').text

  • 7
    используя python 2.7.10 на osx, мне пришлось импортировать ElementTree как from xml.etree.ElementTree import ElementTree
  • 0
    потому что это оболочка C, вы можете столкнуться с трудностями при ее развертывании на AWS Lambda, если вы не скомпилируете экземпляр EC2 или образ Docker AWS Linux
76

пакет lxml поддерживает xpath. Кажется, что это работает очень хорошо, хотя у меня были проблемы с осью "я". Там также Amara, но я не использовал его лично.

  • 3
    lxml определенно упрощает работу с xml с python.
  • 1
    Амара довольно милая, и не всегда нужен xpath.
Показать ещё 2 комментария
38

Звучит как реклама lxml здесь.;) ElementTree включен в библиотеку std. Под 2.6 и ниже его xpath довольно слаб, но в 2.7 значительно улучшен:

import xml.etree.ElementTree as ET
root = ET.parse(filename)
result = ''

for elem in root.findall('.//child/grandchild'):
    # How to make decisions based on attributes even in 2.6:
    if elem.attrib.get('name') == 'foo':
        result = elem.text
        break
38

Используйте LXML. LXML использует всю мощь libxml2 и libxslt, но обертывает их в более "Pythonic" привязки, чем привязки Python, которые являются родными для этих библиотек. Таким образом, он получает полную реализацию XPath 1.0. Native ElemenTree поддерживает ограниченное подмножество XPath, хотя оно может быть достаточно хорошим для ваших нужд.

25

Другим вариантом является py-dom-xpath, он работает с мини-миром и является чистым Python, поэтому работает над appengine.

import xpath
xpath.find('//item', doc)
  • 2
    Проще, чем lxml и libxml2, если вы уже работаете с minidom. Работает красиво и более "Pythonic". context в функции find позволяет использовать другой результат xpath в качестве нового контекста поиска.
  • 2
    Я тоже использовал py-dom-xpath, когда пишу плагин, потому что это чистый python. Но я не думаю, что это больше поддерживается, и помните об этой ошибке («Не удается получить доступ к элементу с именем« text »»): code.google.com/p/py-dom-xpath/issues/detail?id = 8
10

Вы можете использовать:

PyXML

from xml.dom.ext.reader import Sax2
from xml import xpath
doc = Sax2.FromXmlFile('foo.xml').documentElement
for url in xpath.Evaluate('//@Url', doc):
  print url.value

libxml2

import libxml2
doc = libxml2.parseFile('foo.xml')
for url in doc.xpathEval('//@Url'):
  print url.content
  • 0
    когда я пробую код PyXML, я ImportError: No module named ext from xml.dom.ext.reader import Sax2
8

Последняя версия elementtree поддерживает XPath довольно хорошо. Не будучи экспертом XPath, я не могу точно сказать, реализована ли реализация, но она удовлетворила большинство моих потребностей при работе на Python. Я также использую lxml и PyXML, и я считаю, что это удобно, потому что это стандартный модуль.

ПРИМЕЧАНИЕ. С тех пор я нашел lxml, и для меня это определенно лучший XML файл для Python. Он также отлично подходит для XPath (хотя опять-таки, возможно, не полная реализация).

  • 7
    Поддержка ElementTree XPath в настоящее время минимальна в лучшем случае. В функциональности есть огромные дыры, такие как отсутствие селекторов атрибутов, отсутствие осей, отличных от заданных по умолчанию, отсутствие индексации дочерних элементов и т. Д. В версии 1.3 (в альфа-версии) добавлены некоторые из этих функций, но это все еще довольно частичная реализация.
4

Вы можете использовать простой soupparser от lxml

Пример:

from lxml.html.soupparser import fromstring

tree = fromstring("<a>Find me!</a>")
print tree.xpath("//a/text()")
  • 0
    Какая разница с использованием soupparser?
  • 0
    Это просто альтернатива
4

Другая библиотека - 4Suite: http://sourceforge.net/projects/foursuite/

Я не знаю, насколько это соответствует спецификации. Но он очень хорошо работал для моего использования. Он выглядит заброшенным.

3

PyXML работает хорошо.

Вы не сказали, какую платформу вы используете, но если вы на Ubuntu, вы можете получить ее с помощью sudo apt-get install python-xml. Я уверен, что у других дистрибутивов Linux есть это.

Если вы находитесь на Mac, xpath уже установлен, но не сразу доступен. Вы можете установить PY_USE_XMLPLUS в своей среде или сделать это способом Python перед импортом xml.xpath:

if sys.platform.startswith('darwin'):
    os.environ['PY_USE_XMLPLUS'] = '1'

В худшем случае вам, возможно, придется строить его самостоятельно. Этот пакет больше не поддерживается, но все еще прекрасно работает и работает с современными 2.x Pythons. Основные документы здесь.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню