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

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

Ответов (12)

Пакет lxml поддерживает xpath. Кажется, это работает очень хорошо, хотя у меня были проблемы с осью self ::. Еще есть Амара , но лично я ею не пользовался.

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

  1. Соответствие спецификации
  2. Активное развитие и участие сообщества
  3. Скорость. Это действительно оболочка python для реализации C.
  4. Вездесущность. Библиотека libxml2 широко распространена и поэтому хорошо протестирована.

К недостаткам можно отнести:

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

Если вы выбираете простой путь, придерживайтесь 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

Похоже здесь на рекламу в формате 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

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

Пример:

from lxml.html.soupparser import fromstring

tree = fromstring("<a>Find me!</a>")
print tree.xpath("//a/text()")

Если вы хотите, чтобы мощность XPATH сочеталась с возможностью также использовать CSS в любой момент, вы можете использовать parsel:

>>> from parsel import Selector
>>> sel = Selector(text=u"""<html>
        <body>
            <h1>Hello, Parsel!</h1>
            <ul>
                <li><a href="http://example.com">Link 1</a></li>
                <li><a href="http://scrapy.org">Link 2</a></li>
            </ul
        </body>
        </html>""")
>>>
>>> sel.css('h1::text').extract_first()
'Hello, Parsel!'
>>> sel.xpath('//h1/text()').extract_first()
'Hello, Parsel!'

Если он вам понадобится для html :

import lxml.html as html
root  = html.fromstring(string)
root.xpath('//meta')

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'

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

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

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

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

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

import xpath
xpath.find('//item', doc)

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

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

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

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