#html #parsing #xpath
#HTML #синтаксический анализ #xpath
Вопрос:
Есть ли библиотека, которая может предоставить мне XPATH для всех узлов на HTML-странице?
Комментарии:
1. Какой язык вы используете?
2. //node() — это Xpath для всех узлов.
3. Хороший вопрос, 1. Смотрите мой ответ для исчерпывающего решения. 🙂
4. @samplebias: JAVA была бы лучше. но я не возражаю, даже если это PHP или Perl.
5. @Стивен Д. Маевский: Нет. Это не так.
Ответ №1:
есть ли какая-либо библиотека, которая может предоставить мне XPATH для всех узлов на HTML-странице
Да, если эта HTML-страница является правильно сформированным XML-документом.
В зависимости от того, что вы понимаете под «узлом»…
//*
выбирает все элементы в документе.
/descendant-or-self::node()
выбирает все элементы, текстовые узлы, инструкции по обработке, узлы комментариев и корневой узел /
.
//text()
выбирает все текстовые узлы в документе.
//comment()
выбирает все узлы комментариев в документе.
//processing-instruction()
выбирает все инструкции по обработке в документе.
//@*
выбирает все узлы атрибутов в документе.
//namespace::*
выбирает все узлы пространства имен в документе.
Наконец, вы можете объединить любое из приведенных выше выражений, используя оператор union ( |
).
Таким образом, я считаю, что следующее выражение действительно выбирает «все узлы» любого XML-документа:
/descendant-or-self::node() | //@* | //namespace::*
Комментарии:
1.
//node()
не выбирает корневой каталог, потому что он расширен до/descendant-or-self::node()/child::node()
. На самом делеnode()
шаблон не соответствует корню документа.2. @Alejandro: Хороший улов, исправлено. Что касается выбора корня документа, он по-прежнему совпадает,
node()
как вancestor::node()
илиself::node()
3. Извините, я должен был сказать »
node()
как шаблон» .4. Просто нашел это полезным для Delphi
Ответ №2:
На случай, если это кому-то еще пригодится, если вы используете python / lxml, вам сначала нужно создать дерево, а затем запросить это дерево с помощью путей XPATH, которые Dimitre перечисляет выше.
Чтобы получить дерево:
import lxml
from lxml import html, etree
your_webpage_string = "<html><head><title>test<body><h1>page title</h3>"
bad_html = lxml.html.fromstring(your_webpage_string)
good_html = etree.tostring(root, pretty_print=True).strip()
your_tree = etree.fromstring(good_html)
all_xpaths = your_tree.xpath('//*')
В последней строке замените ‘//*’ на любой xpath, который вы хотите. all_xpaths
теперь список выглядит следующим образом:
[<Element html at 0x7ff740b24b90>,
<Element head at 0x7ff740b24d88>,
<Element title at 0x7ff740b24dd0>,
<Element body at 0x7ff740b24e18>,
<Element h1 at 0x7ff740b24e60>]