Як використовувати Xpath в Python?


224

Які бібліотеки підтримують Xpath? Чи є повна реалізація? Як використовується бібліотека? Де знаходиться його веб-сайт?


4
У мене є така підступна підозра, що відповіді на це питання зараз трохи несвіжі.
Warren P

4
Відповідь @ gringo-suave виглядає як вдале оновлення. stackoverflow.com/a/13504511/1450294
Майкл Шепер

Scrap пропонує селектори XPath .
cs95

Як говорить @WarrenP, більшість відповідей тут є надзвичайно устареним старим Python-2.x, дійсно застарілим. Можливо, це питання слід позначити python-2.x
smci

Відповіді:


129

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


8
використовуючи python 2.7.10 на osx, мені довелося імпортувати ElementTree якfrom xml.etree.ElementTree import ElementTree
Ben Page

оскільки це обгортка C, у вас можуть виникнути труднощі при його розгортанні до AWS Lambda, якщо ви не компілюєте на примірник EC2 або зображення Docker з AWS Linux
CpILL

85

Пакет lxml підтримує xpath. Здається, це працює досить добре, хоча у мене були проблеми з self :: axis. Також є Amara , але я не використовував її особисто.


1
amara дуже приємна, і не завжди потрібен xpath.
gatoatigrado

Будь ласка, додайте основні деталі щодо використання XPath з lxml.
jpmc26

56

Тут звучить реклама 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

39

Використовуйте LXML. LXML використовує повну потужність libxml2 та libxslt, але вкладає їх у більше "пітонічні" прив'язки, ніж зв'язки Python, які є рідними для цих бібліотек. Таким чином, він отримує повну реалізацію XPath 1.0. Native ElemenTree підтримує обмежений набір XPath, хоча це може бути досить добре для ваших потреб.


29

Інший варіант - py-dom-xpath , він працює з minidom і є чистим Python, тому працює на аппенгіні.

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

2
Простіше, ніж lxml та libxml2, якщо ви вже працюєте з minidom. Прекрасно працює і є більш «пітонічним». contextУ findфункції дозволяють використовувати інший результат XPATH в якості нового пошуку контексту.
Бен

3
Я теж використовую py-dom-xpath, коли пишу плагін, тому що це чистий python. Але я не думаю, що це більше не підтримується, і пам’ятайте про цю помилку ("Неможливо отримати доступ до елемента, ім'я якого" текст ""): code.google.com/p/py-dom-xpath/isissue/detail?id = 8
Джон Кумбс


14

Ви можете використовувати:

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

коли я пробую код PyXML, я отримав ImportError: No module named extвідfrom xml.dom.ext.reader import Sax2
Aminah Nuraini

9

Остання версія елемента дерева досить добре підтримує XPath. Не будучи експертом XPath, я не можу сказати точно, чи реалізація повна, але вона задовольнила більшість моїх потреб під час роботи в Python. Я також використовую lxml та PyXML, і мені здається, що etree є приємним, оскільки це стандартний модуль.

ПРИМІТКА: з тих пір я знайшов lxml і для мене, безумовно, найкраща XML-версія для Python. Це добре також робить XPath (хоча, можливо, не повну реалізацію).


7
Підтримка XPath ElementTree в даний час в кращому випадку мінімальна. Існує величезна кількість пробілів у функціональних можливостях, таких як відсутність селекторів атрибутів, відсутні осі за замовчуванням, відсутність дочірньої індексації тощо. Версія 1.3 (в альфа) додає деякі з цих функцій, але це все ще безсоромна часткова реалізація.
Джеймс Брейді


7

Якщо ви хочете мати потужність 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!'

як повинен виглядати мій Xpath, якщо я хочу отримати "Посилання 1" та "Посилання 2"?
weefwefwqg3

1
для отримання тексту він повинен бути чимось на кшталт//li/a/text()
eLRuLL

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. Основні документи тут .


0

Якщо вам це знадобиться для html :

import lxml.html as html
root  = html.fromstring(string)
root.xpath('//meta')
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.