Какие библиотеки поддерживают XPath? Есть полная реализация? Как используется библиотека? Где его веб-сайт?
Ответ @ gringo-suave выглядит как хорошее обновление. stackoverflow.com/a/13504511/1450294
Scrapy предлагает Селекторы XPath.
Как говорит @WarrenP, большинство ответов здесь - чрезвычайно устаревший старый Python-2.x, действительно устаревший. Может, этот вопрос стоит пометить python-2.x






lxml пакет поддерживает xpath. Кажется, это работает очень хорошо, хотя у меня были проблемы с осью self ::. Еще есть Амара, но лично я им не пользовался.
Амара довольно хороша, и не всегда нужен xpath.
Добавьте основные сведения о том, как использовать XPath с lxml.
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. Базовая документация - здесь.
Последняя версия элементдерево довольно хорошо поддерживает XPath. Не будучи экспертом по XPath, я не могу точно сказать, полная ли реализация, но она удовлетворила большинство моих потребностей при работе на Python. Я также использую lxml и PyXML, и мне нравится etree, потому что это стандартный модуль.
ПРИМЕЧАНИЕ. С тех пор я нашел lxml, и для меня это определенно лучшая библиотека XML для Python. Он также отлично справляется с XPath (хотя, возможно, и не полностью).
Поддержка XPath в ElementTree в настоящее время в лучшем случае минимальна. Существуют огромные пробелы в функциональности, такие как отсутствие селекторов атрибутов, отсутствие осей по умолчанию, отсутствие дочерней индексации и т. д. Версия 1.3 (в альфа-версии) добавляет некоторые из этих функций, но это все еще бесстыдно частичная реализация.
libxml2 имеет ряд преимуществ:
К недостаткам можно отнести:
Если вы выбираете простой путь, придерживайтесь ЭлементДерево (который включен в 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используя python 2.7.10 на osx, мне пришлось импортировать ElementTree как from xml.etree.ElementTree import ElementTree
поскольку это оболочка C, вы можете столкнуться с трудностями при развертывании ее в AWS Lambda, если вы не скомпилируете ее на экземпляре EC2 или образе Docker для AWS Linux.
Строгость - не недостаток.
Используйте LXML. LXML использует все возможности libxml2 и libxslt, но оборачивает их более "питоническими" привязками, чем привязки Python, которые являются родными для этих библиотек. Таким образом, он получает полную реализацию XPath 1.0. Собственный ElemenTree поддерживает ограниченное подмножество XPath, хотя может быть достаточно хорошим для ваших нужд.
Другой вариант - py-dom-xpath, он без проблем работает с minidom и является чистым Python, поэтому работает с appengine.
import xpath
xpath.find('//item', doc)
Проще, чем lxml и libxml2, если вы уже работаете с minidom. Красиво работает и более "питоничен". context в функции find позволяет использовать другой результат xpath в качестве нового контекста поиска.
Я тоже использовал py-dom-xpath, когда пишу плагин, потому что это чистый питон. Но я не думаю, что он больше поддерживается, и я знаю об этой ошибке («Невозможно получить доступ к элементу с именем 'text'»): code.google.com/p/py-dom-xpath/issues/detail?id=8
Другая библиотека - 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
когда я пробую код PyXML, я получаю ImportError: No module named ext от from xml.dom.ext.reader import Sax2
Похоже здесь на рекламу в формате 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!'
как должен выглядеть мой Xpath, если я хочу получить «Ссылка 1» и «Ссылка 2»?
для получения текста это должно быть что-то вроде //li/a/text()
Если он вам понадобится для html:
import lxml.html as html
root = html.fromstring(string)
root.xpath('//meta')
У меня есть подлое подозрение, что ответы на этот вопрос сейчас немного устарели.