Как найти список всех HTML-тегов, которые активны на определенных данных - PullRequest
1 голос
/ 07 ноября 2019

Я хочу проанализировать HTML, чтобы преобразовать его в другой формат, сохранив при этом некоторые стили (полужирный шрифт, списки и т. Д.).

Чтобы лучше объяснить, что я имею в виду,

Рассмотримследующий код:

<html>
<body>

<h2>A Nested List</h2>
<p>List <b>can</b> be nested (lists inside lists):</p>

<ul>
  <li>Coffee</li>
  <li>Tea
    <ul>
      <li>Black tea</li>
      <li>Green tea</li>
    </ul>
  </li>
  <li>Milk</li>
</ul>

</body>
</html>

Теперь, если бы я должен был выбрать слово «Список» в начале абзаца, мой вывод должен быть (html, body, p), так как эти теги активны наслово "Список".

Другой пример, если бы я выбрал слово "Черный чай", мой вывод должен быть (html, body, ul, li, ul, li), так как он является частью вложенногоlist.

Я видел, как Chrome Инспектор делает это, но я не уверен, как я могу сделать это в коде с помощью Python.

Вот изображение того, что показывает Chrome инспектор: Chrome Inspector

Я попытался выполнить разбор HTML-кода, используя Beautiful soup, и, хотя это потрясающе для получения данных, я не смог решить свою проблему, используя его.

Позже я попробовал html-парсер для этой же проблемы, пытаясь сделать стек всех тегов перед «данными»и высовывал их, когда я сталкивался с соответствующими конечными тегами, но я тоже не мог этого сделать.

1 Ответ

0 голосов
/ 07 ноября 2019

Как вы сказали в своем комментарии, он может или не может дать вам то, что вы хотите, но это может быть началом. Поэтому я все равно попробую и посмотрим, что произойдет:

from lxml import etree
snippet = """[your html above]"""
root = etree.fromstring(snippet)

tree = etree.ElementTree(root)
targets = ['List','nested','Black tea']
for e in root.iter():
    for target in targets:
        if (e.text and  target in e.text) or (e.tail and target in e.tail):
            print(target,' :',tree.getpath(e))    

Вывод будет

List  : /html/body/h2
List  : /html/body/p
nested  : /html/body/p/b
Black tea  : /html/body/ul/li[2]/ul/li[1]

Как вы можете видеть, это дает вам xpath для выбранных текстовых целей. Несколько вещей, на которые стоит обратить внимание: во-первых, «Список» появляется дважды, потому что он появляется дважды в тексте. Второе: xpath «Черный чай» содержит позиционные значения (например, [2] in /li[2]), которые указывают, что целевая строка появляется во втором li элементе фрагмента и т. Д. Если вам не нужночто вам может потребоваться убрать эту информацию из вывода (или использовать другой инструмент).

...