GKE*_*GKE 5 python beautifulsoup python-3.x
我一直在尝试使用BeautifulSoup4和递归来捕获HTML页面的布局.我们的想法是将父项的数据结构链接到子项,例如,这样的布局:
<html>
<h1>
<!--Contents-->
</h1>
<div>
<div>
<!--Contents-->
</div>
</div>
</html>
Run Code Online (Sandbox Code Playgroud)
将存储在如下列表中:
html = [ h1 , div ] # Where h1 and div are also lists also containing lists
Run Code Online (Sandbox Code Playgroud)
我很难找到关于这个特定问题的Q&A,所以我尝试使用递归遍历目录来建模函数,因为它们非常相似.
这是我在Python 3中的当前函数,它应该将标记嵌入到列表中:
def listGen(l , hObj):
# Where hObj is a BS4 object and l is a sorted lists containing direct children to the html tag
z = []
for x in l:
z.append(hObj.find(x).children)
def expand(xlist1):
# Where xlist1 is a list generator
for n in xlist1:
if n.name is not None:
print(n.name)
for n2 in hObj.find(n.name).children:
if n2.name is not None:
print(n2.name , "--") #Debugging print
return z #Temporary
for x in z:
print("------")
expand(x , 0)
return z
Run Code Online (Sandbox Code Playgroud)
解析维基百科主页给出了以下输出:
------
h1
img --
div --
div
div --
strong --
div
div --
strong --
div
div --
strong --
div
div --
strong --
div
div --
strong --
hr
div
div --
strong --
p
small --
small --
small --
script
script
script
style
------
meta
title
meta
script
meta
link
link
link
style
style
link
link
Run Code Online (Sandbox Code Playgroud)
这正是我所需要的,但它需要两个for循环,并将需要更多来获得孩子的所有孩子.此外,我不知道有多少标签嵌套在未来的网站上.所以我把expand功能改为:
def expand(xlist1 , depth):
l1 = list(xlist1)
if depth < len(l1):
for n in l1[depth]:
if n is not None:
if hObj.find(l1[depth].name).children:
return expand(hObj.find(l1[depth].name).children , 0)
if n is None:
print(2) # Debugging print
return expand(xlist1 , depth + 1)
if depth >= len(l1):
return 0 # Temporary
return 0 # Temporary
Run Code Online (Sandbox Code Playgroud)
只是为了给我最大的递归错误,我尝试了很多其他的变化都无济于事.
我已多次浏览BS4 Docs,似乎没有内置功能.任何建议或这不是一个可行的方式来实现我正在寻找的东西?
小智 5
我不认为嵌套列表正是您在这里寻找的。如果您要做的只是构建一棵标签树,我会使用嵌套字典。如果您尝试提取任何其他信息,我仍然会使用它们。
这个递归函数将构建一个嵌套字典“树”
def traverse(soup):
if soup.name is not None:
dom_dictionary = {}
dom_dictionary['name'] = soup.name
dom_dictionary['children'] = [ traverse(child) for child in soup.children if child.name is not None]
return dom_dictionary
Run Code Online (Sandbox Code Playgroud)
我们可以像这样使用它:
page = requests.get("http://example.com")
soup = BeautifulSoup(page.text, "html5lib")
traverse(soup)
Run Code Online (Sandbox Code Playgroud)
这给了我们:
{'name': '[document]',
'children': [{'name': 'html',
'children': [{'name': 'head',
'children': [{'name': 'title', 'children': []},
{'name': 'meta', 'children': []},
{'name': 'meta', 'children': []},
{'name': 'meta', 'children': []},
{'name': 'style', 'children': []}]},
{'name': 'body',
'children': [{'name': 'div',
'children': [{'name': 'h1', 'children': []},
{'name': 'p', 'children': []},
{'name': 'p', 'children': [{'name': 'a', 'children': []}]}]}]}]}]}
Run Code Online (Sandbox Code Playgroud)