Beautiful Soup是一个强大的解析工具,它借助网页的结构和属性等特性来解析网页。只需要简单的几条语句,就可以完成网页中某个元素的提取。利用它可以省去很多烦琐的提取工作,提高了解析效率。
html=''' <div class="panel"> <div class="panel-heading"> <h4>Hello</h4> </div>
<div class="panel-body"> <ul class="list" id="list-1">
<li class="element">Foo</li> <li class="element">Bar</li> <li class="elernent" >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.find_all(name='ul')[0])
#根据属性,可以用soup.find_all(id = 'list-2'})
print(soup.find_all(attrs={'id':'list-2'}))
首先声明变量html,它是一个HTML字符串。但是需要注意的是,它并不是一个完整的HTML字符串,因为body和html节点都没有闭合。接着我们将它当作第一个参数传给BeautifulSoup对象,该对象的第二个参数为解析器的类型(这里使用 lxml ),此时就完成了BeaufulSoup对象的初始化。然后将这个对象赋值给soup变量。接下来,就可以调用soup的各个方法和属性解析这串HTML代码了。首先调用find_all方法,查询所有符合条件的元素。传入name参数,其参数值为ul。也就是说,我们想要查询所有ul节点,返回结果是列表类型,长度为2,每个元素依然都是bs4.element.Tag类型。
最后查询的时候传入的是attrs参数,参数的类型是字典类型。比如,要查询id为list-2的节点,可以传入attrs={'id':'list-2'}的查询条件,得到的结果是列表形式,包含的内容就是符合id为list-2的所有节点。除了find_all方法,还有find方法,只不过后者返回的是单个元素,也就是第一个匹配的元素,而前者返回的是所有匹配的元素组成的列表。
除了上面2个查询,还有一些如下:
1、find_parents和find_parent:前者返回所有祖先节点 ,后者返回直接父节点。
2、find_next_siblings和find_next_sibling:前者返回后面所有的兄弟节点,后者返回后面第一个兄弟节点。
3、find_previous_siblings和find_previous_sibling:前者返回前面所有的兄弟节点,后者返回前面第一个兄弟节点。
4、find_all_next和find_next:前者返回节点后所有符合条件的节点,后者返回第一个符合条件的节点。
5、find_all_previous和find_previous:前者返回节点后所有符合条件的节点,后者返回第一个符合条件的节点。
Beautiful Soup还提供了另外一种选择器,那就是css选择器。
print(soup.select('ul li'))
是选择所有ul节点下面的所有li节点,结果便是所有的li节点组成的列表。
select方法同样支持嵌套选择。例如先选择所有ul节点,再遍历每个ul节点,选择其li节点
for ul in soup.select('ul'):
print(ul.select('li'))
我们知道节点类型是Tag类型,所以获取属性还可以用原来的方法。这里尝试获取每个ul节点的id属性:
for ul in soup.select('ul'):
print(ul['id'])
print(ul.attrs['id'])
直接传入中括号和属性名,以及通过attrs属性获取属性值,都可以成功。