如果没有有关您的数据的更多信息,很难为您提供涵盖所有可能输入的简洁解决方案。为了帮助您顺利上路,这里有一个演练,希望能引导您找到适合您需求的解决方案。
以下将为我们提供<div id="a">
(应该只有一个具有特定 id 的元素):
top_div = soup.find('div', {'id':'a'})
然后我们可以继续检索所有内部 div class='aa'
(可能有多个):
aa_div = top_div.findAll('div', {'class':'aa'})
从那里,我们可以返回找到的每个 div 的所有链接:
links = [div.findAll('a') for div in aa_div]
请注意,links
包含嵌套列表,因为div.findAll('a')
将返回a
找到的节点列表。有多种方法可以展平这样的列表。
这是一个遍历列表并打印出各个链接的示例:
>>> from itertools import chain
>>> for a in chain.from_iterable(links):
... print a
...
<a id="ff" href="#">ff</a>
<a id="gg" href="#">gg</a>
上面提出的解决方案相当冗长。然而,随着对输入数据的更多了解,更紧凑的解决方案是可能的。例如,如果数据与您显示的完全一样,并且总会有那个数据div
,class='aa'
那么解决方案可能只是:
>>> soup.find('div', {'class':'aa'}).findAll('a')
[<a id="ff" href="#">ff</a>, <a id="gg" href="#">gg</a>]
将 CSS 选择器与 BeautifulSoup4 一起使用
如果您使用的是较新版本的 BeatifulSoup(版本 4),您还可以使用提供CSS 选择器支持的.select()
方法。我在此答案开头提供的详尽解决方案可以重写为:
soup.select("div#a div.aa a")
对于 BeautifulSoup v3,您可以使用soupselect添加此功能。
但是,请注意文档中的以下声明(强调我的):
这为了解 CSS 选择器语法的用户提供了便利。您可以使用 Beautiful Soup API 完成所有这些工作。如果你只需要 CSS 选择器,你还不如直接使用 lxml,因为它更快。但这可以让您将简单的 CSS 选择器与 Beautiful Soup API 结合起来。