HTML的特点在于标签的层级顺序。例如,<html>
标签包含了<body>
标签,而在<body>
标签内可能会有一个<div>
标签,进一步地,<div>
标签中可能分别嵌套有<ul>
和<li>
元素。findChildren()
方法和.children
属性都返回一个包含直接位于某个元素下的所有子标签的ResultSet(列表)。通过遍历这个列表,你可以获得位于所需位置的子标签,即第n个子标签。
下面的代码使用HTML文档中的<div>
标签的.children
属性。由于.children
属性的返回类型是一个列表迭代器,我们将从中获取一个Python列表。我们还需要从迭代器中移除空白和换行符。一旦完成,我们就可以获取所需的子标签。在此示例中,显示的是<div>
标签的索引为1的子元素。
示例
from bs4 import BeautifulSoup, NavigableString
markup = '''
<div id="Languages">
<p>Java</p> <p>Python</p> <p>C++</p>
</div>
'''
soup = BeautifulSoup(markup, 'html.parser')
tag = soup.div
children = tag.children
childlist = [child for child in children if child not in ['\n', ' ']]
print(childlist[1])
输出
<p>Python</p>
如果要使用findChildren()
方法而不是.children
属性,可以将语句更改为:
children = tag.findChildren()
输出将不会改变。
一种更有效的方式来定位第n个子元素是使用select()
方法。select()
方法使用CSS选择器从当前元素中获取所需的PageElement。
Soup和Tag对象通过它们的.css
属性支持CSS选择器,这是一个对CSS选择器API的接口。选择器的实现是由Soup Sieve包处理的,该包是在安装bs4包时一同安装的。
Soup Sieve包定义了不同类型的选择器,包括简单的、复合的和复杂的CSS选择器,这些选择器由一个或多个类型选择器、ID选择器、类选择器组成。这些选择器是在CSS语言中定义的。
Soup Sieve中也有伪类选择器。一个CSS伪类是在选择器中添加的一个关键字,用于指定所选元素的一种特殊状态。在此示例中,我们将使用:nth-child
伪类选择器。因为我们需要从<div>
标签中选择第2个位置的子元素,所以我们传递:nth-child(2)
给select_one()
方法。
示例
from bs4 import BeautifulSoup, NavigableString
markup = '''
<div id="Languages">
<p>Java</p> <p>Python</p> <p>C++</p>
</div>
'''
soup = BeautifulSoup(markup, 'html.parser')
tag = soup.div
child = tag.select_one(':nth-child(2)')
print(child)
输出
<p>Python</p>
我们得到了与使用findChildren()
方法相同的结果。注意,子元素编号是从1开始的,而不是像Python列表那样从0开始。