получить XPATH для всех узлов

#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>]