• Python 页面解析:Beautiful Soup库的使用


    ✅作者简介:人工智能专业本科在读,喜欢计算机与编程,写博客记录自己的学习历程。
    🍎个人主页:小嗷犬的博客
    🍊个人信条:为天地立心,为生民立命,为往圣继绝学,为万世开太平。
    🥭本文内容:Python 页面解析:Beautiful Soup库的使用



    Beautiful Soup库简介

    Beautiful Soup 简称 BS4(其中 4 表示版本号)是一个 Python 中常用的页面解析库,它可以从 HTML 或 XML 文档中快速地提取指定的数据。

    相比于之前讲过的 lxml 库,Beautiful Soup 更加简单易用,不像正则和 XPath 需要刻意去记住很多特定语法,尽管那样会效率更高更直接。

    对大多数 Python 使用者来说,好用会比高效更重要。

    Beautiful Soup库为第三方库,需要我们通过pip命令安装:

    pip install bs4
    
    • 1

    BS4 解析页面时需要依赖文档解析器,所以还需要一个文档解析器。
    Python 自带了一个文档解析库 html.parser, 但是其解析速度稍慢,所以我们结合上篇内容(Python 文档解析:lxml库的使用),安装 lxml 作为文档解析库:

    pip install lxml
    
    • 1

    Beautiful Soup库方法介绍

    使用 bs4 的初始化操作,是用文本创建一个 BeautifulSoup 对象,并指定文档解析器:

    from bs4 import BeautifulSoup
    
    html_str = '''
    
    '''
    
    soup = BeautifulSoup(html_str, 'lxml')
    # prettify()用于格式化输出HTML/XML文档
    print(soup.prettify())
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    bs4 提供了find_all()find()两个常用的查找方法它们的用法如下:

    find_all()

    find_all() 方法用来搜索当前 tag 的所有子节点,并判断这些节点是否符合过滤条件,最后以列表形式将符合条件的内容返回,语法格式如下:

    find_all(name, attrs, recursive, text, limit)
    
    • 1

    参数说明:

    • name:查找所有名字为 name 的 tag 标签,字符串对象会被自动忽略。
    • attrs:按照属性名和属性值搜索 tag 标签,注意由于 class 是 Python 的关键字,所以要使用 “class_”。
    • recursive:find_all() 会搜索 tag 的所有子孙节点,设置 recursive=False 可以只搜索 tag 的直接子节点。
    • text:用来搜文档中的字符串内容,该参数可以接受字符串 、正则表达式 、列表、True。
    • limit:由于 find_all() 会返回所有的搜索结果,这样会影响执行效率,通过 limit 参数可以限制返回结果的数量。
    from bs4 import BeautifulSoup
    
    html_str = '''
    
    '''
    soup = BeautifulSoup(html_str, 'lxml')
    
    print(soup.find_all("li"))
    print(soup.find_all("a"))
    print(soup.find_all(text="Python"))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    上面程序使用 find_all() 方法,来查找页面中所有的

  • 标签、标签和"Python"字符串内容。

    find()

    find() 方法与 find_all() 方法极其相似,不同之处在于 find() 仅返回第一个符合条件的结果,因此 find() 方法也没有limit参数,语法格式如下:

    find(name, attrs, recursive, text)
    
    • 1

    除了和 find_all() 相同的使用方式以外,bs4find() 方法提供了一种简写方式:

    soup.find("li")
    soup.li
    
    • 1
    • 2

    这两行代码的功能相同,都是返回第一个

  • 标签,完整程序:

    from bs4 import BeautifulSoup
    
    html_str = '''
    
    '''
    soup = BeautifulSoup(html_str, 'lxml')
    
    print(soup.li)
    print(soup.a)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    上面的程序会打印出第一个

  • 标签和第一个标签。

    select()

    bs4 支持大部分的 CSS 选择器,比如常见的标签选择器、类选择器、id 选择器,以及层级选择器。Beautiful Soup 提供了一个 select() 方法,通过向该方法中添加选择器,就可以在 HTML 文档中搜索到与之对应的内容。

    应用如下:

    from bs4 import BeautifulSoup
    
    html_str = '''
    
    '''
    soup = BeautifulSoup(html_str, 'lxml')
    #根据元素标签查找
    print(soup.select('body'))
    #根据属性选择器查找
    print(soup.select('a[href]'))
    #根据类查找
    print(soup.select('.web'))
    #后代节点查找
    print(soup.select('div ul'))
    #根据id查找
    print(soup.select('#web1'))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    更多方法及其详细使用说明,请参见官方文档:
    https://beautiful-soup-4.readthedocs.io/en/latest/


    代码实例

    学会了 Beautiful Soup ,让我们试着改写一下上次的爬虫代码吧:

    import os
    import sys
    import requests
    from bs4 import BeautifulSoup
    
    x = requests.get('https://www.csdn.net/')
    
    soup = BeautifulSoup(x.text, 'lxml')
    
    img_list = soup.select('img[src]')
    
    # 创建img文件夹
    os.chdir(os.path.dirname(sys.argv[0]))
    
    if not os.path.exists('img'):
        os.mkdir('img')
        print('创建文件夹成功')
    else:
        print('文件夹已存在')
    
    # 下载图片
    for i in range(len(img_list)):
        item = img_list[i]['src']
        img = requests.get(item).content
        if item.endswith('jpg'):
            with open(f'./img/{i}.jpg', 'wb') as f:
                f.write(img)
        elif item.endswith('jpeg'):
            with open(f'./img/{i}.jpeg', 'wb') as f:
                f.write(img)
        elif item.endswith('png'):
            with open(f'./img/{i}.png', 'wb') as f:
                f.write(img)
        else:
            print(f'第{i + 1}张图片格式不正确')
            continue
        print(f'第{i + 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

    这就是本文的全部内容了,快去动手试试吧!

  • 相关阅读:
    题目 94 递归实现排列型枚举
    Druid 查询超时配置的探究 → DataSource 和 JdbcTemplate 的 queryTimeout 到底谁生效?
    基于boost库的站内搜索引擎
    聊聊powerjob的执行机器地址
    计算机网络--网络层
    Docker进入容器出现:bash: vi: command not found
    【CSDN 竞赛—第10期】所有题目解法的思考和总结
    数据结构起步——时间与空间复杂度
    不科学,RocketMQ生产者在一个应用服务竟然不能向多个NameServer发送消息
    C语言基础代码总结(右下角有目录)
  • 原文地址:https://blog.csdn.net/qq_63585949/article/details/126762330