• Python爬虫技术之Beautiful Soup相关最全详细技术


    Beautiful Soup技术

    一、基本过程

    在这里插入图片描述
    官方文档链接: Beautiful Soup官方文档

    二、初始化Beautiful Soup对象

    1、 从bs4库中导入BeautifulSoup类实例化一个对象

    from bs4 import BeautifulSoup
    soup = BeautifulSoup(markup,features)
    
    • 1
    • 2

    1.2 其中两个参数的作用

    1.2.1 markup

    (1)解释

    被解析的HTML字符串或文件内容

    (2)两种使用方式
            使用字符串变量
    
    • 1
    #使用html_str字符串变量
    from bs4 import BeautifulSoup
    soup = BeautifulSoup(html_str)
    
    • 1
    • 2
    • 3
            使用open( )函数打开文件
    
    • 1
    #假设将html_str字符串写入index.html
    from bs4 import BeautifulSoup
    soup = BeautifulSoup(open(index.html))
    
    • 1
    • 2
    • 3

    1.2.2 features

    (1) 解释

    解析器的类型

    (2)两种使用方式
          指定解析器(BeautifulSoup选择指定的解析器来解析文档)
    
    • 1
    #指定lxml作为解析器
    from bs4 import BeautifulSoup
    soup = BeautifulSoup(html_str,'lxml')
    
    • 1
    • 2
    • 3
         未指定解析器(BeautifulSoup选择最默认的解析器来解析文档)
    
    • 1
    #解析html_str选择最默认的解析器
    from bs4 import BeautifulSoup
    soup = BeautifulSoup(html_str)
    
    • 1
    • 2
    • 3

    三、BeautifulSoup选择器

    1、选择器分类

       节点选择器(获取数据的基本方法)
       方法选择器(查找、定位元素的常用选择)
       CSS选择器(查找、定位元素的常用选择)
    
    • 1
    • 2
    • 3

    2、选择器作用

       查找、定位元素、并获取数据
    
    • 1

    3、思维图

    在这里插入图片描述

    4、节点选择器

    节点选择器就是使用tag对象来选择节点元素。而tag对象与HTML、XML的原生文档中的Tag相同,即标签。

    <title>The Dorcument story</title>
    <a href="...." id="...">Bob</a>
    
    • 1
    • 2

    title和a标签里的内容成为Tag对象

    #例如
    print(soup.title)
    
    • 1
    • 2

    4.1 格式

    4.1.1 获取元素

           格式:soup.tag
           返回值:节点元素
    
    • 1
    • 2
    html_str = """ <html><head><title>The www</title></head>
    <body>
    <p class="title">The www</p>
    <a href="..." class="sister" id="link1">Bob</a>
    <a href="..." class="sister" id="link2">Tese</a>
    </body>
    """
    
    #1、导入Beautiful Soup类
    from bs4 import BeautifulSoup
    
    #2、传入参数,实例化这个类
    soup = BeautifulSoup(html_str)
    
    #3、定位元素title
    print(soup.title)
    
    #4、查看获取到的结果的类型 获取到的元素的类型是Tag类的对象
    print(type(soup.title))
    
    #5、当html中存在多个相同的节点的时候,只会提取第一个节点
    print(soup.a)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    4.2 提取信息的方法

    4.2.1 获取名称

            格式:soup.tag.name
            返回值:字符串
    
    • 1
    • 2
    #例一
    #获取a标签的名字
    soup.a.name
    
    #输出结果
    a
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    4.2.2 获取属性

            格式:  soup.tag.attrs
            返回值:   字典
    
    • 1
    • 2
    #例二
    #获取a标签的属性
    soup.a.attrs
    
    #输出结构
    {'href':'http://exmaple.com','class':['sister'],'id':'link1'}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    4.2.3 获取内容

          格式:soup.tag.string
          返回值:字符串
    
    • 1
    • 2
    #例三
    #获取a标签的内容
    soup.a.string 
    
    #输出结构
    Bob
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    4.2.4 总体样例

    html_str = """ <html><head><title>The www</title></head>
    <body>
    <p class="title">The www</p>
    <a href="..." class="sister" id="link1">Bob</a>
    <a href="..." class="sister" id="link2">Tese</a>
    </body>
    """
    
    #1、导入Beautiful Soup类
    from bs4 import BeautifulSoup
    
    #2、传入参数,实例化这个类
    soup = BeautifulSoup(html_str)
    
    #3、获取a标签的名称
    print(soup.a.name)
    
    #4、查看a标签名称的类型
    print(type(soup.a.name))
    
    #5、获取a标签的属性
    print(soup.a.attrs)
    
    #6、获取a标签的值
    print(soup.a.string)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    4.3 嵌套选择的方法

    格式:soup.tag.tag
    返回值: 节点元素

    html_str = """ <html><head><title>The www</title></head>
    <body>
    <p class="title">The www</p>
    <a href="..." class="sister" id="link1">Bob</a>
    <a href="..." class="sister" id="link2">Tese</a>
    </body>
    """
    
    #1、导入Beautiful Soup类
    from bs4 import BeautifulSoup
    
    #2、传入参数,实例化这个类
    soup = BeautifulSoup(html_str)
    
    #3、获取head的子节点title
    print(soup.head.title)
    
    #4、获取head的子节点title的类型
    print(type(soup.head.title))
    
    #5、获取head的子节点title的内容
    print(soup.head.title.string)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    4.4 关联选择的方法

    在做选择的时候,有时候不能做到一步就选到想要的节点元素,需要先选中某一个节点元素,然后以他为基准再选择他的子节点、父节点、兄弟节点等。

    4.4.1 子节点

             格式:soup.tag.contents
             返回值:   列表
              
             格式:soup.tag.children
             返回值:生成器
    
    • 1
    • 2
    • 3
    • 4
    • 5
    html_str = """ <html><head><title>The www</title></head>
    <body>
    <p class="title">The www</p>
    <a href="..." class="sister" id="link1">Bob</a>
    <a href="..." class="sister" id="link2">Tese</a>
    </body>
    """
    
    #1、导入Beautiful Soup类
    from bs4 import BeautifulSoup
    
    #2、传入参数,实例化这个类
    soup = BeautifulSoup(html_str)
    
    #3、获取p标签的子节点
    print(soup.p.contents)
    
    #4、获取p标签的子节点children
    print(soup.p.children)
    
    for i,child in enumerate(soup.p.children):
        print(i,child)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    4.4.2 父节点

            格式:soup.tag.parent
            返回值:  节点元素
    
    • 1
    • 2
    html_str = """ <html><head><title>The www</title></head>
    <body>
    <p class="title">The www</p>
    <a href="..." class="sister" id="link1">Bob</a>
    <a href="..." class="sister" id="link2">Tese</a>
    </body>
    """
    
    #1、导入Beautiful Soup类
    from bs4 import BeautifulSoup
    
    #2、传入参数,实例化这个类
    soup = BeautifulSoup(html_str)
    
    #3、获取a标签的父节点 parent
    print(soup.a.parent)
    
    #4、获取a节点的祖先节点 parents
    print(soup.a.parents)
    
    print(list(enumerate(soup.a.parents)))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    4.4.3 兄弟节点

    (1)获取后面一个节点
            格式:soup.tag.next_sibling
            返回值:  节点元素
    
    • 1
    • 2
    (2)获取后面所有的节点
             格式:soup.tag.next_siblings
             返回值:  生成器
    
    • 1
    • 2
    (3)获取前面一个节点
              格式:soup.tag.previous_sibling
               返回值:节点元素
    
    • 1
    • 2
    (4)获取前面所有的节点
               格式:soup.tag.previous_siblings
               返回值:  生成器
    
    • 1
    • 2
    html_str = """ <html><head><title>The www</title></head>
    <body>
    <p class="title">The www</p>
    <a href="..." class="sister" id="link1">Bob</a>
    <a href="..." class="sister" id="link2">Tese</a>
    </body>
    """
    
    #1、导入Beautiful Soup类
    from bs4 import BeautifulSoup
    
    #2、传入参数,实例化这个类
    soup = BeautifulSoup(html_str)
    
    #3、获取a节点的兄弟节点 next_sibling
    print(soup.a.next_sibling)
    
    #4、获取a节点的所有兄弟节点 next_siblings
    print(soup.a.next_siblings)
    
    print(list(enumerate(soup.a.next_siblings)))
    
    #5、获取a节点的前面一个节点 previous_sibling
    print(soup.a.previous_sibling)
    
    #6、获取a节点的前面的所有节点,previous_siblings
    print(soup.a.previous_siblings)
    
    print(list(enumerate(soup.a.previous_siblings)))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    5、CSS选择器

    主要分支和内容
    在这里插入图片描述

    5.1 获取元素

    使用CSS选择器,只需要调用select( )方法,并结合CSS选择器语法就可以定位元素的位置。
    格式:soup.select( )

    5.2 CSS选择器语法

    5.2.1 id选择器

    id选择器需要使用#来定位元素,例如:获取第一个ul节点 #list-1

    5.2.2 类选择器

    类选择器需要使用 . 来定位元素,例如:获取所有的ul . list

    5.2.3 标签选择器

    标签选择器需要使用标签来进行选择,例如:获取h4

    5.2.4 混合使用

    获取第一个ul中的li节点 例如:.panel-body #list-1 li

    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">Jay</li>
              </ul>
              <ul class="list list-small" id="list-2">
                    <li class="element">Foo</li>
                    <li class="element">Bar</li>
              </ul>
         </div>
    </div>
    '''
    
    
    #1、导入Beautiful Soup类
    from bs4 import BeautifulSoup
    
    #2、传入参数,实例化这个类
    soup = BeautifulSoup(html)
    
    #3、获取class="panel-heading"的div
    print(soup.select(".panel .panel-heading"))
    
    #4、获取所有的li节点 标签选择器
    print(soup.select("ul li"))
    
    #5、获取所有的li节点 类选择器
    print(soup.select(".list .element"))
    
    #6、获取第二个ul的li节点 id选择器
    print(soup.select("#list-2 li"))
    
    #7、获取第二个ul的li节点 类选择器
    print(soup.select(".list-small li"))
    
    #8、获取第二个ul节点 列表获取
    print(soup.select("ul")[1])
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    5.3 CSS选择器高级用法

    5.3.1 嵌套选择

    先选择一个节点,再获取这个节点下面的子节点

    
    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">Jay</li>
              </ul>
              <ul class="list list-small" id="list-2">
                    <li class="element">Foo</li>
                    <li class="element">Bar</li>
              </ul>
         </div>
    </div>
    '''
    
    
    #1、导入Beautiful Soup类
    from bs4 import BeautifulSoup
    
    #2、传入参数,实例化这个类
    soup = BeautifulSoup(html)
    
    #3、获取ul节点
    print(soup.select("ul"))
    
    #4、查看ul节点的类型
    print(type(soup.select("ul")))
    
    for ul in soup.select("ul"):
        print(ul)
        print(type(ul))
        print(ul.select("li"))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    5.3.2 获取属性

    css选择器获取属性的方法和节点选择器获取属性的方法一样,使用attrs属性来获取。

    
    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">Jay</li>
              </ul>
              <ul class="list list-small" id="list-2">
                    <li class="element">Foo</li>
                    <li class="element">Bar</li>
              </ul>
         </div>
    </div>
    '''
    
    
    #1、导入Beautiful Soup类
    from bs4 import BeautifulSoup
    
    #2、传入参数,实例化这个类
    soup = BeautifulSoup(html)
    
    #3、获取li节点
    print(soup.select("#list-2 li"))
    
    for li in soup.select("#list-2 li"):
        print(type(li))
        print(li.attrs)
        print(li.attrs['class'])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    5.3.3 获取文本

    css选择器获取文本的方法和节点选择器获取文本的方法一样,使用string和strings属性来获取

    
    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">Jay</li>
              </ul>
              <ul class="list list-small" id="list-2">
                    <li class="element">Foo</li>
                    <li class="element">Bar</li>
              </ul>
         </div>
    </div>
    '''
    
    
    #1、导入Beautiful Soup类
    from bs4 import BeautifulSoup
    
    #2、传入参数,实例化这个类
    soup = BeautifulSoup(html)
    
    #3、获取li节点
    print(soup.select("#list-2 li"))
    
    for li in soup.select("#list-2 li"):
        print(type(li))
        print(li.string)
        
    #4、获取ul节点
    print(soup.select("#list-2"))
    
    for ul in soup.select("#list-2"):
        print(type(ul))
        print(ul.strings)
        print(list(ul.strings))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    6、方法选择器

    在这里插入图片描述

    6.1 find_all( )方法

    6.1.1 作用及范围

    6.1.1.1 作用

    用于搜索当前节点的所有符合条件的节点

    6.1.1.2 范围

    当前节点下的所有节点,如果没有指定当前节点,则进行全文的搜索

    6.1.1.3 用法
    find_all(name,attrs,recursive,text,**kwargs)
    
    • 1

    6.1.2 name参数

    6.1.2.1 作用

    查找所有名字为name的节点(tag对象)

    6.1.2.2 参数形式
    (1)字符串

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

    #寻找所有span标签
    print(soup.find_all(name="span"))
    
    
    • 1
    • 2
    • 3
    (2)正则表达式

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

    import re
    for tag in soup.find_all(re.compile('^b')):
        print(tag.name)
    
    • 1
    • 2
    • 3
    (3) 列表

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

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

    True可以匹配任何值

    #使用True选择文件中所有标签
    for tag in soup.find_all(True):
        print(tag.name)
    
    • 1
    • 2
    • 3
    6.1.2.3 样例
    
    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">
                   <span>Foo</span>
                   </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>
    '''
    
    
    #1、导入Beautiful Soup类
    from bs4 import BeautifulSoup
    
    #2、传入参数,实例化这个类
    soup = BeautifulSoup(html)
    
    #3、获取span标签 字符串
    print(soup.find_all(name="span"))
        
    #4、获取span标签  正则表达式  模型对象
    import re
    reg = re.compile('^sp')
    print(soup.find_all(name=reg))
    
    #5、获取a和span标签列表
    print(soup.find_all(name=['a','span']))
    
    #6、True的用法 递归的获取所有的标签
    print(soup.find_all(name=True))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    6.1.3 attrs参数

    6.1.3.1 作用

    查询含有接受的属性值的标签

    6.1.3.2 参数形式

    字典类型

    #获取id为link1的标签
    print(soup.find_all(attrs={id:'link1'}))
    
    • 1
    • 2

    6.1.4 kwargs参数

    6.1.4.1 作用

    接收常用的属性参数,如id 和 class

    6.1.4.2 参数形式

    变量赋值的形式

    #获取id为link1的标签
    print(soup.find_all(id='link1'))
    
    • 1
    • 2

    6.1.5 text参数

    6.1.5.1 作用

    查询含有接收的文本的标签

    6.1.5.2 参数形式

    字符串
    通过搜索文档中的字符串内容,来确定文件标签

    #获取文本中包含Elsie内容
    print(soup.find_all(text='Elsie'))
    
    • 1
    • 2

    也可以与其他参数混合使用来过滤tag

    #获取文本中包含Elsie内容的标签
    print(soup.find_all('a',text='Elsie'))
    
    • 1
    • 2

    6.1.6 limit参数

    6.1.6.1 作用

    用于限制返回结果的数量

    6.1.6.2 参数形式

    整数

    #获取前两个a标签
    print(soup.find_all('a',limit=2))
    
    • 1
    • 2

    6.1.7 recursive参数

    6.1.7.1 作用

    决定是否获取子孙节点

    6.1.7.2 参数形式

    布尔值,默认是True

    print(soup.find_all('title',recursive=False))
    
    • 1

    6.1.8 样例

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

    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">
                   <span>Foo</span>
                   </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>
    '''
    
    
    #1、导入Beautiful Soup类
    from bs4 import BeautifulSoup
    
    #2、传入参数,实例化这个类
    soup = BeautifulSoup(html)
    
    #3、使用attrs获取id为link1的标签
    print(soup.find_all(attrs={'id':'link1'}))
    
    #4、使用kwargs获取class等于sister的标签
    print(soup.find_all(class='sister'))
    
    #5、使用text获取包含story的标签
    import re
    print(soup.find_all(name='b',text=re.compile('.*?story')))
    
    #6、使用limit限制p标签的查询只获取第一个
    print(soup.find_all(name='p',limit=1))
    
    #7、使用recursive限制第一个p标签的查询
    print(soup.find_all('p',limit=1,recursive=False))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    6.2 find()方法

    6.2.1 作用

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

    6.2.2 区别

    find_all( ) 方法返回所有符合条件的元素列表(查找当前节点下,符合条件的所有节点)
    find( ) 方法就是返回符合条件的第一个元素(查找当前节点下,符合条件的第一个节点)

    6.2.3 可供使用参数

    name, attrs, text, kwargs, recursive (没有limit参数)

  • 相关阅读:
    Moleculer微服务02
    auto 推导
    前端常用的几种加密方法
    vsftpd 操作手册 - 完整版
    Ansible自动化运维
    day54
    excel绘制直方图
    【uni-app】初体验
    凌雄科技打造DaaS模式,IT设备产业链由内而外嬗变升级
    【Qt】QMainWindow
  • 原文地址:https://blog.csdn.net/qq_46106857/article/details/125618285