我从一个简单的HTML结构开始,如下所示:
感谢@alecxe的帮助,我能够创建这个JSON词典:
{u'Outer List': {u'Inner List': [u'info 1', u'info 2', u'info 3']}}
使用他的代码:
from bs4 import BeautifulSoup
data = """your html goes here: see the very end of post"""
soup = BeautifulSoup(data)
inner_ul = soup.find('ul', class_='innerUl')
inner_items = [li.text.strip() for li in inner_ul.ul.find_all('li')]
outer_ul_text = soup.ul.span.text.strip()
inner_ul_text = inner_ul.span.text.strip()
result = {outer_ul_text: {inner_ul_text: inner_items}}
print result
代码太棒了,我一直试图以可迭代的方式重写它。
我的真实' HTML数据集更大,更糟糕,我需要以我能处理的方式扩展代码:
或者,数据看起来可能是这样的:
更糟糕的是,或许在sublist
之下我们还有另一个sublist
!最终,这是我的真实情况。
我的问题是:我无法找到一种方法来概括上述的BeautifulSoup代码来处理上述任何一种情况(更不用说第三种情况了!甚至更糟糕的情况!)。
当我无法预先访问HTML的确切结构时,如何递归/迭代地检测HTML的深度并提取信息? BeautifulSoup甚至可以实现这一点吗?当然必须有一些方法可以让我失踪,先确定深度,然后继续。
非常感谢你做到这一点!
最后一个示例的HTML在这里:
<html>
<body>
<ul class="rootList">
<li class="liItem endPlus">
<span class="itemToBeAdded">
Outer List
</span>
</li>
<li class="noBulletsLi ">
<ul class="innerUl">
<li class="liItem crossPlus">
<span class="itemToBeAdded">
Inner List
</span>
<ul class="grayStarUl ">
<li class="">
<span class="phrasesToBeAdded">
info 1
</span>
</li>
<li class="">
<span class="phrasesToBeAdded">
info 2
</span>
</li>
<li class="">
<span class="phrasesToBeAdded">
info 3
</span>
<ul class="grayStarUl">
<li class="">
<span class="phrasesToBeAdded">sublist</span>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</body>
</html>
答案 0 :(得分:3)
你可以编写两个递归调用的解析器:
def parse_list(tag):
return map(parse_list_item, tag.find_all('li', recursive=False))
def parse_list_item(tag):
text = tag.find(text=True, recursive=False).strip()
text += '\n' + tag.span.text.strip() if tag.span.parent == tag else ''
inner = tag.find('ul', recursive=False)
if inner is None: # no more nesting:
return text.strip()
else: # more nesting
return {text.strip():parse_list(inner)} if text else parse_list(inner)
上面没有使用任何class
信息,无论内部列表的深度如何都应该有效:
>>> parse_list(soup.find('ul'))
[u'Outer List', [{u'Inner List': [u'info 1', u'info 2', {u'info 3': [u'sublist']}]}]]
答案 1 :(得分:0)
我对你想要达到的目标有点不确定。因此,我假设您想从所有跨度中提取数据,而不关心结构。如果你更准确地解释你想要实现的目标,我会更新我的答案。
soup = BeautifulSoup(html_doc)
spans = soup.findall(class="phrasesToBeAdded")
text = []
for element in spans:
text.append(element.get_text())