Глубина первого обхода на BeautifulSoup дерево разбора

есть ли способ сделать DFT на дереве синтаксического анализа BeautifulSoup? Я пытаюсь сделать что-то вроде начала с корня, обычно , получить все дочерние элементы, а затем для каждого дочернего элемента получить своих детей и т. д., Пока я не достигну терминального узла, в котором я построю свой путь обратно по дереву. Проблема в том, что я не могу найти метод, который позволит мне это сделать. Я нашел метод findChildren, но, похоже, просто поместил всю страницу в список несколько раз с каждой последующей записью сокращается. Я мог бы использовать это для обхода, однако, кроме последней записи в списке, не представляется, что есть какой-либо способ идентифицировать записи как терминальные узлы или нет. Есть идеи?

2 ответов


recursiveChildGenerator() уже делает это:

soup = BeautifulSoup.BeautifulSoup(html)
for child in soup.recursiveChildGenerator():
     name = getattr(child, "name", None)
     if name is not None:
         print name
     elif not child.isspace(): # leaf node, don't print spaces
         print child

выход

для html из @msalvadores это:

html
ul
li
Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
li
Aliquam tincidunt mauris eu risus.
li
Vestibulum auctor dapibus neque.
html

Примечание: html печатается дважды из-за пример содержит два открытие <html> теги.


Я думаю, вы можете использовать метод "childGenerator" и рекурсивно использовать его для анализа дерева в DFT-режиме.

def recursiveChildren(x):
   if "childGenerator" in dir(x):
      for child in x.childGenerator():
          name = getattr(child, "name", None)
          if name is not None:
             print "[Container Node]",child.name
          recursiveChildren(child)
    else:
       if not x.isspace(): #Just to avoid printing "\n" parsed from document.
          print "[Terminal Node]",x

if __name__ == "__main__":
    soup = BeautifulSoup(your_data)
    for child in soup.childGenerator():
        recursiveChildren(child)

С "childGenerator" in dir(x) мы удостоверяемся, что элемент является контейнером, терминальными узлами, такими как NavigableStrings не являются контейнерами и не содержат детей.

для некоторого примера HTML как:

<html>
<ul>
   <li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li>
   <li>Aliquam tincidunt mauris eu risus.</li>
   <li>Vestibulum auctor dapibus neque.</li>
</ul>
</html>

печатает сценарии ...

[Container Node] ul
[Container Node] li
[Terminal Node] Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
[Container Node] li
[Terminal Node] Aliquam tincidunt mauris eu risus.
[Container Node] li
[Terminal Node] Vestibulum auctor dapibus neque.