blc*_*llo 10 python beautifulsoup tree-traversal
有没有办法在BeautifulSoup解析树上进行DFT?我正在尝试做一些事情,比如从根开始,通常,获取所有子元素,然后为每个子元素获取他们的孩子等,直到我点击终端节点,此时我将建立我的方式备份树.问题是我似乎找不到允许我这样做的方法.我找到了findChildren方法,但这似乎只是将整个页面放在一个列表中多次,每个后续条目都减少了.我可能能够使用它来进行遍历,但是除了列表中的最后一个条目之外,它似乎没有任何方法可以将条目标识为终端节点.有任何想法吗?
jfs*_*jfs 11
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
Run Code Online (Sandbox Code Playgroud)
对于来自@ 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
Run Code Online (Sandbox Code Playgroud)
注意: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)
Run Code Online (Sandbox Code Playgroud)
随着"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>
Run Code Online (Sandbox Code Playgroud)
这个脚本打印...
[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.
Run Code Online (Sandbox Code Playgroud)