python beautifulsoup python beautifulsoup4( 三 )


<generator object Tag.descendants at 0x000001D77A90E570>0钢铁知识库1 <a class="钢铁学数据分析" href="http://a.com" id="link1"><span>Elsie</span></a>2 3 <span>Elsie</span>4 Elsie5 6 7 <a class="钢铁学自动化" href="http://b.com" id="link2">Lacie</a>8 Lacie9and10 <a class="cccc" href="http://example.com" id="link3">Tillie</a>11 Tillie12钢铁学爬虫.
此时返回结果还是生成器 。遍历输出一下可以看到,这次的输出结果就包含了 span 节点 。descendants 会递归查询所有子节点,得到所有的子孙节点 。
除此之外,还有父节点parent 和祖先节点parents,兄弟节点next_siblingprevious_siblings 日常用得少不再演示,后续需要自行查官方文档即可 。
方法选择器
前面聊的通过属性选择节点,但如果进行比较复杂的话还是比较繁琐 。幸好BeautifulSoup还为我们提供另外一些查询方法,比如find_all 和 find,调用他们传入相应参数就可以灵活查询 。
find_all
顾名思义,就是查询所有符合条件的元素,可以给它传入一些属性或文本来得到符合条件的元素,功能十分强大 。
它的 API 如下:
find_all(name , attrs , recursive , text , **kwargs)
我们可以根据节点名来查询元素,下面我们用一个实例来感受一下:
html5='''<div class="panel"><div class="panel-heading"><h4>Hello</h4></div><div class="panel-body"><ul class="list" id="list-1"><li class="element">钢铁</li><li class="element">知识</li><li class="element">仓库</li></ul><ul class="list list-small" id="list-2"><li class="element">python</li><li class="element">java</li></ul></div></div>'''from bs4 import BeautifulSoupsoup = BeautifulSoup(html5, 'lxml')print(soup.find_all(name='ul'))print(type(soup.find_all(name='ul')[0]))'''[<ul class="list" id="list-1"><li class="element">钢铁</li><li class="element">知识</li><li class="element">仓库</li></ul>, <ul class="list list-small" id="list-2"><li class="element">python</li><li class="element">java</li></ul>]<class 'bs4.element.Tag'>'''
可以看到返回了一个列表,分别是两个ul长度为2,且类型依然是bs4.element.Tag类型 。
因为都是Tag类型,所以依然可以继续嵌套查询,还是同样文本,查询ul节点后再继续查询内部li节点 。
from bs4 import BeautifulSoupsoup = BeautifulSoup(html5, 'lxml')for ul in soup.find_all(name='ul'):print(ul.find_all(name='li'))'''[<li class="element">钢铁</li>, <li class="element">知识</li>, <li class="element">仓库</li>][<li class="element">python</li>, <li class="element">java</li>]'''
返回结果是列表类型,元素依然是Tag类型 。
接下来我们可以遍历每个li获取它的文本:
for ul in soup.find_all(name='ul'):print(ul.find_all(name='li'))for li in ul.find_all(name='li'):print(li.string)'''[<li class="element">钢铁</li>, <li class="element">知识</li>, <li class="element">仓库</li>]钢铁知识仓库[<li class="element">python</li>, <li class="element">java</li>]pythonjava'''
find
除了 find_all 方法,还有 find 方法,不过 find 方法返回的是单个元素,也就是第一个匹配的元素,而 find_all 返回的是所有匹配的元素组成的列表 。示例如下:
html5='''<div class="panel"><div class="panel-heading"><h4>Hello</h4></div><div class="panel-body"><ul class="list" id="list-1"><li class="element">钢铁</li><li class="element">知识</li><li class="element">仓库</li></ul><ul class="list list-small" id="list-2"><li class="element">python</li><li class="element">java</li></ul></div></div>'''from bs4 import BeautifulSoupsoup = BeautifulSoup(html5, 'lxml')print(soup.find(name='ul'))print(type(soup.find(name='ul')))print(soup.find(class_='list'))'''<ul class="list" id="list-1"><li class="element">钢铁</li><li class="element">知识</li><li class="element">仓库</li></ul><class 'bs4.element.Tag'><ul class="list" id="list-1"><li class="element">钢铁</li><li class="element">知识</li><li class="element">仓库</li></ul>'''


推荐阅读