CSS选择器
Beautiful Soup还提供了另外一个选择器,那就是CSS选择器。
使用CSS选择器时,只需要调用select()方法,传入相应的CSS选择器即可,示例如下:
html = '''
<div class="panel">
<div class="panel-heading">
<h4>Hello</h4>
<div class="panel-body">
<ul class="list" id="list-1">
<li class="element">Foo</li>
<li class="element">Bar</li>
<li class="element">Jay</li>
</ul>
<ul class="list list-small" id="list-2">
<li class="element">Foo</li>
<li class="element">Bar</li>
</ul>
</div>
</div>
'''
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.select('.panel .panel-heading'))
print(soup.select('ul li'))
print(soup.select('#list-2 .element'))
print(type(soup.select('ul')[0]))
运行结果如下:
[<div class="panel-heading">
<h4>Hello</h4>
<div class="panel-body">
<ul class="list" id="list-1">
<li class="element">Foo</li>
<li class="element">Bar</li>
<li class="element">Jay</li>
</ul>
<ul class="list list-small" id="list-2">
<li class="element">Foo</li>
<li class="element">Bar</li>
</ul>
</div>
</div>]
[<li class="element">Foo</li>, <li class="element">Bar</li>, <li class="element">Jay</li>, <li class="element">Foo</li>, <li class="element">Bar</li>]
[<li class="element">Foo</li>, <li class="element">Bar</li>]
<class 'bs4.element.Tag'>
这里我们用了3次CSS选择器,返回的结果均是符合CSS选择器的节点组成的列表。例如,select(‘ul li’)则是选择所有ul节点下面的所有里节点,结果便是所有的li节点组成的列表。
最后一句打印输出了列表中元素的类型。可以看到,类型依然是Tag类型。
嵌套选择
select()方法同样支持嵌套选择。例如,先选择所有ul节点,再里边每个ul节点,选择其li节点,样例如下:
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
for ul in soup.select('ul'):
print(ul.select('li'))
运行结果如下:
[<li class="element">Foo</li>, <li class="element">Bar</li>, <li class="element">Jay</li>]
[<li class="element">Foo</li>, <li class="element">Bar</li>]
可以看到,这里正常输出了所有ul节点下所有里节点组成的列表。
获取属性
我们知道节点类型是Tag类型,所以获取属性还可以用原来的方法。仍然是上面的HTML文本,这里尝试获取每个ul节点的id属性:
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
for ul in soup.select('ul'):
print(ul['id'])
print(ul.attrs['id'])
运行结果如下:
list-1
list-1
list-2
list-2
可以看到,直接传入中括号和属性名,以及通过attrs属性获取属性值,都可以成功。
获取文本
要获取文本,当然也可以用前面所提的string属性。此外,还有一个方法,那就是get_text(),实例如下:
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
for li in soup.select('li'):
print('Get Text:', li.get_text())
print('String:', li.string)
运行结果如下:
Get Text: Foo
String: Foo
Get Text: Bar
String: Bar
Get Text: Jay
String: Jay
Get Text: Foo
String: Foo
Get Text: Bar
String: Bar
可以看到,二者效果完全一致。
Beautiful Soup的基本用法总结
- 推荐使用lxml解析库,必要时使用html.parser。
- 节点选择筛选功能弱但是速度快。
- 建议使用find()或者find_all()查询匹配单个结果或者多个结果。
- 如果对CSS选择器熟悉的话,可以使用select()方法选择。