有没有办法在 BeautifulSoup 解析树上做 DFT?我正在尝试做一些事情,例如从根开始,通常,获取所有子元素,然后为每个子元素获取他们的子元素,等等,直到我点击一个终端节点,此时我将建立我的方式备份树. 问题是我似乎找不到允许我这样做的方法。我找到了 findChildren 方法,但这似乎只是将整个页面多次放入列表中,并且每个后续条目都会减少。我也许可以使用它来进行遍历,但是除了列表中的最后一个条目之外,它似乎没有任何方法可以将条目标识为终端节点。有任何想法吗?
问问题
12675 次
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
注意:html
由于示例包含两个开始<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 回答