菜鸟笔记
提升您的技术认知

Beautiful Soup方法选择器

阅读 : 760

Beautiful Soup是Python的一个网页解析库,处理快捷; 支持多种解析器,功能强大。教程细致讲解Beautiful Soup的深入使用、节点选择器、CSS选择器、Beautiful Soup4的方法选择器等重要知识点,是学好爬虫的基础课程。

1. 了解Beautiful Soup的方法选择器

前面所讲的选择方法都是通过标签和属性来选择的,这种方法非常快,但是如果在比较复杂的页面中选择元素,无法精准的定位到元素。

比如:

<a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;

在HTML文档中存在多个<a>标签,我们无法使用节点选择器精准的定位到第二、第三个<a>标签。所以我们在这里学习findall()find()方法,通过传入参数的方法,来进行精准的定位。

前置代码

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="element">]ay</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')

2.方法选择器之 find_all() 方法

学习目标

  1. 掌握find_all()方法中的参数的用法

2.1 作用及范围:

  • 作用:用于搜索当前节点的所有符合条件的节点
  • 范围:当前节点下的所有节点,如果没有指定当前节点,则进行全文的搜索

1.2 用法介绍:

find_all(name, attrs, recursive, text, **kwargs)

(1.) name参数

如图所示,name 参数的作用是用来查找所有名字为名字的节点(tag对象)。在使用的时候,可以接收字符串、正则表达式、列表、布尔值。

参数形式:字符串

传入一个字符串参数,即标签名(tag),Beautiful Soup会查找与字符串内容完全匹配的内容

# 寻找所有span标签
print(soup.find_all('span'))

# 输出结果
[<span>Elsie</span>]
参数形式:正则表达式

传入正则表达式,Beautiful Soup会通过正则表达式的match()函数来匹配内容

# 使用正则匹配以b开头的标签
import re

for tag in soup.find_all(re.compile('^b')):
    print(tag.name)
    
# 输出结果
body
参数形式:列表

传入列表参数,Beautiful Soup会将与列表中任一元素匹配,并返回结果。

# 使用列表选择包含a和span的所有标签
print(soup.find_all(['a', 'span']))

# 输出结果
[<a class="sister" href="http://example.com/elsie" id="link1"><span>Elsie</span></a>, <span>Elsie</span>, <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>, <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]
参数形式:布尔值True

True可以匹配任何值

# 使用True选择文件中所有标签
for tag in soup.find_all(True):
    print(tag.name)
    
# 输出结果
html
head
title
body
p
a
span
a
a
p

(2.) attrs参数

  • 作用:查询含有接受的属性值的标签
  • 参数形式:字典类型
    # 获取id为link1的标签
    print(soup.find_all(attrs={
        id: 'link1'}))
    
    # 输出结果
    [<a class="sister" href="http://example.com/elsie" id="link1"><span>Elsie</span></a>]
    

(3.) kwargs参数

  • 作用:接收常用的属性参数,如idclass

  • 参数形式:变量赋值的形式

    # 获取id为link1的标签
    print(soup.find_all(id='link1'))
    
    # 输出结果
    [<a class="sister" href="http://example.com/elsie" id="link1"><span>Elsie</span></a>]
    

    这里直接传入id=‘link1’,就查询到id为’link1’的节点元素了。而对于class来说,它在Python中是一个关键字,需要加一个下划线,即class_=‘element’。

    # 获取id为link1的标签
    print(soup.find_all(class_='story'))
    
    # 输出结果
    [<p class="story">Once upon a time there were three little sisters; and their names were
    <a class="sister" href="http://example.com/elsie" id="link1"><span>Elsie</span></a>,
    <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a> and
    <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>;
    and they lived at the bottom of a well.</p>, <p class="story">...</p>]
    

(4.) text参数

  • 作用:查询含有接收的文本的标签
  • 参数形式:字符串
  • 通过搜索文档中的字符串内容,来确定文件标签。
    # 获取文本中包含Elsie内容
    print(soup.find_all(text='Elsie'))
    
    # 输出结果
    ['Elsie']
    

    虽然text参数用于搜索字符串,还可以与其他参数混合使用来过滤tag

    # 获取文本中包含Elsie内容的标签
    print(soup.find_all('a', text='Elsie'))
    
    # 输出结果
    [<a class="sister" href="http://example.com/elsie" id="link1"><span>Elsie</span></a>]
    

(5.) limit参数

  • 作用:用于限制返回结果的数量
  • 参数形式:整数
    # 获取前两个a标签
    print(soup.find_all('a', limit=2))
    
    # 输出结果
    [<a class="sister" href="http://example.com/elsie" id="link1"><span>Elsie</span></a>, <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>]
    

(6.) recursive参数

  • 作用:决定是否获取子孙节点
  • 参数形式:布尔值,默认是True
    print(soup.find_all('title'))
    print(soup.find_all('title', recursive=False))
          
    # 输出结果
    [<title>The Dormouse's story</title>]
    []
    

3. 方法选择器之find()方法

find()方法和find_all()方法类似,作用都是在文档中查找需要的信息

区别点在于:

  • find_all()方法返回所有符合条件的元素列表,而find()方法就是返回符合条件的第一个元素
  • 除了limit参数不能在find()方法中使用,find()方法的其他参数和find_all()的参数用法一样

find()方法

  • 作用:查找当前节点下,符合条件的一个元素节点
  • 范围:当前节点下的一个元素

(1.) name参数

# 获取a标签
print(soup.find('a'))

# 输出结果
<a class="sister" href="http://example.com/elsie" id="link1"><span>Elsie</span></a>

(2.) attrs参数

# 获取class等于sister的标签
print(soup.find(attrs={
  'class': 'sister'}))

# 输出结果
<a class="sister" href="http://example.com/elsie" id="link1"><span>Elsie</span></a>

(3.) kwargs参数

  • 作用:接收常用的属性参数,如idclass
  • 参数形式:变量赋值的形式
# 获取class等于sister的标签
print(soup.find(class_='sister'))

# 输出结果
<a class="sister" href="http://example.com/elsie" id="link1"><span>Elsie</span></a>

(4.) text参数

  • 作用:查询含有接收的文本的标签
  • 参数形式:字符串
  • 通过搜索文档中的字符串内容,来确定文件标签。
# 获取文本中包含story的标签
print(soup.find(text=re.compile('.*?story')))

# 输出结果
The Dormouse's story

(5.) recursive参数

  • 作用:决定是否获取子孙节点
  • 参数形式:布尔值,默认是True
# 获取文本中包含story的标签
print(soup.find('a', recursive=False)

# 输出结果
None

4. 其他的方法介绍

在Beautiful Soup中还存在其他的方法,根据自己的业务需求使用就行可以。参数的用法相同,唯一的区别点在于搜索的范围。

5. 总结

find_all()方法的使用

  1. name参数用来接收tag名称,有四种形式:字符串,正则,列表和True
  2. attrs参数用来接收属性的键值对字典
  3. kwargs参数用来接收常用属性的变量赋值的形式 例如:id='link1'class_="sister"
  4. text参数用来接收文本信息
  5. limit参数用来限制返回结果的数量
  6. recursive参数用来决定是否获取子孙节点

查询范围

find()方法:

  • 查找当前节点下,符合条件的第一个节点

find_all()方法:

  • 查找点前节点下,符合条件的所有节点

可供使用的参数

find()方法:

  • nameattrstextkwargsrecursive

find_all()方法:

  • nameattrstextkwargsrecursivelimit

在大多数的情况下,find()方法配合find_all()方法就已经能够满足工作需求,如果遇到特殊情况,需要查询特殊的范围,可以使用Beautiful Soup的其他方法。