有没有办法在BeautifulSoup解析树上进行DFT?我正在尝试做一些事情,比如从根开始,通常,获取所有子元素,然后为每个子元素获取他们的孩子等等,直到我点击终端节点,此时我将建立我的方式备份树。问题是我似乎找不到允许我这样做的方法。我找到了findChildren方法,但这似乎只是将整个页面放在一个列表中多次,每个后续条目都减少了。我可能能够使用它来进行遍历,但是除了列表中的最后一个条目之外,它似乎没有任何方法可以将条目标识为终端节点。有什么想法吗?
答案 0 :(得分:10)
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's answer的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
打印两次,因为the example包含两个打开<html>
标记。
答案 1 :(得分:5)
我认为您可以使用方法“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.