15

BeautifulSoup解析ツリーでDFTを実行する方法はありますか?私はルートから始めて、通常はすべての子要素を取得し、次に子要素ごとに子を取得するなどのことをしようとしています。ターミナルノードに到達するまで、ツリーに戻る方法を構築します。 。問題は、これを可能にする方法が見つからないように見えることです。findChildrenメソッドを見つけましたが、それはページ全体をリストに複数回入れ、後続の各エントリが削減されるようです。これを使用してトラバーサルを実行できる可能性がありますが、リストの最後のエントリ以外に、エントリをターミナルノードとして識別する方法は表示されません。何か案は?

4

2 に答える 2

16

mytag.find_all()すでにそれを行います:

mytag.find_all()を呼び出すと、Beautiful Soupはmytagのすべての子孫(その子、その子の子など)を調べます。

from bs4 import BeautifulSoup  # pip install beautifulsoup4

soup = BeautifulSoup("""<!doctype html>
<div id=a>A
  <div id=1>A1</div>
  <div id=2>A2</div>
</div>
<div id=b>B
  <div id=I>BI</div>
  <div id=II>BII</div>
</div>
""")

for div in soup.find_all("div", recursive=True):
    print(div.get('id'))

出力

a
1
2
b
I
II

出力は、それが深さ優先探索であることを確認します。


古い美しいスープ3の答え:

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

出力

@msalvadoresの回答からのhtmlの場合:

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

注:例には2つの開始タグが含まれhtmlているため、2回印刷されます。<html>

于 2011-01-27T10:53:48.643 に答える
6

メソッド「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.
于 2011-01-27T09:27:12.090 に答える