• 【python】爬虫系列之爬虫解析器BeautifulSoup4


    目录

     一、BeautifulSoup4库简单介绍

    二、beautifulsoup4的使用

    1. 基础操作

    2. 对象种类

    3. find_all()搜索文档树

    4. CSS选择器


    活动地址:CSDN21天学习挑战赛

    **

    学习日记 Day18

    **

     一、BeautifulSoup4库简单介绍

    BeautifulSoup4是一个可以从HTML或XML中提取数据的python库。它能够通过你喜欢的转换器实现管用的文档导航、查找、修改文档的方式。BeautifulSoup会帮你节省数小时甚至数天的工作时间。

    BeautifulSoup4将网页转换为一颗DOM树:

     ⚪ 下载BeautifulSoup4模块

    在cmd命令中输入pip install beautifulsoup4命令,安装即可。

    ⚪ beautifulsoup4解析库

    BeautifulSoup在解析时实际上依赖解析器,它除了支持python标准库中的HTML解析器外,还支持一些第三方解析器(比如xml):

    解析器使用方法优势劣势
    python标准库BeautifulSoup(html,'html.parser')pyhton内置标准库、执行速度适中、文档容错能力强python2.7.3及python3.2.2之前的版本文档容错能力差

    lxml

    HTML解析库

    BeautifulSoup(html,'lxml')速度快、文档容错能力强需要安装C语言库
    lxml XML解析库BeautifulSoup(html,'xml')速度快、唯一支持的XML的解析器需要安装C语言库
    htm5lib解析库BeautifulSoup(html,'html5llib')最好的容错性、以浏览器的方式解析文档、生成HTMLS格式的文档速度慢、不依赖外部扩展

    常用的解析器是lxml HTML解析器,其次是html5lib。

    二、beautifulsoup4的使用

    1. 基础操作

    ⚪ 读取HTML字符串

    1. from bs4 import BeautifulSoup
    2. html='''
    3. Hello

    • Foo
  • Bar
  • Jay
    • Foo
    • Bar
    • '''
    • # 创建对象
    • soup = BeautifulSoup(html,'lxml')
    • ⚪ 读取HTML文件

      1. from bs4 import BeautifulSoup
      2. # 创建对象
      3. soup = BeautifulSoup(open('test.html'),'lxml')

      ⚪ 基本方法

      1. from bs4 import BeautifulSoup
      2. html='''
      3. Hello

        • Foo
        • Bar
        • Jay
          • Foo
          • Bar
          • '''
          • # 创建对象
          • soup = BeautifulSoup(html,'lxml')
          • # 缩进格式
          • print(soup.prettify()) # 以缩进格式打印html字符串
          • print('*'*50)
          • # 获取title标签的所有内容
          • print(soup.title)
          • # 获取title标签的名称
          • print(soup.title.name)
          • # 获取title标签的文本内容
          • print(soup.title.string)
          • # 获取head标签的所有内容
          • print(soup.head)
          • # 获取第一个div标签中的所有内容
          • print(soup.div)
          • # 获取第一个div标签的id的值
          • print(soup.div['id'])
          • # 获取第一个a标签中的所有内容
          • print(soup.a)
          • # 获取所有的a标签中的所有的内容
          • print(soup.find_all('a'))
          • # 获取id='ul
          • print(soup.find(id='ul'))
          • # 获取所有的a标签,并遍历打印a标签的文本值
          • for item in soup.find_all('a'):
          • print(item.get('href'))
          • # 获取所有的a标签,并遍历打印a标签的文本值
          • for item in soup.find_all('a'):
          • print(item.get_text())

          2. 对象种类

          BeautifulSoup将复杂HTML文档转换成一个复杂的树形结构,每个节点都是python对象,所有对象可以归纳为4种:Tag,NavigableString,BeautifulSoup,Comment。

          ⚪ Tag,通俗说就是HTML种的一个个标签,比如:

          1. soup = BeautifulSoup('Extremely bold','lxml')
          2. tag = soup.b
          3. print(tag)
          4. print(type(tag))

          显示结果:

          1. <b class="boldest">Extremely boldb>
          2. <class 'bs4.element.Tag'>

          Tag有很多方法和属性,这里介绍tag种最重要的属性name和attributes。

          name属性:

          1. # 输出tag的name
          2. print(tag.name) # 打印 b
          3. # 如果改变了tag的name,将影响所有通过当前Beautiful Soup对象生成的HTML文档
          4. tag.name='b1'
          5. print(tag) # 打印 Extremely bold

          Attributes属性:

          1. # 获取class属性
          2. print(tag['class']) # 输出 ['boldest']
          3. # 直接获取属性
          4. print(tag.attrs) # 输出 {'class': ['boldest']}

          tag的属性可以被添加、修改和删除:

          1. # 添加 id 属性
          2. tag['id'] = 1
          3. print(tag)
          4. # 修改 class 属性
          5. tag['class'] = 'tl1'
          6. print(tag)
          7. # 删除 class 属性
          8. del tag['class']
          9. print(tag)

          显示结果:

          1. <b1 class="boldest" id="1">Extremely boldb1>
          2. <b1 class="tl1" id="1">Extremely boldb1>
          3. <b1 id="1">Extremely boldb1>

          ⚪ NavigableString,用.string获取标签内部的文字。

          1. print(soup.b.string) # 输出 Extremely bold
          2. print(type(soup.b.string)) # 输出

          ⚪ BeautifulSoup,表示一个文档的内容,可以获取它的类型、名称以及属性。

          1. print(soup.name) # 输出 [document]
          2. print(type(soup.name)) # 输出
          3. print(soup.attrs) # 文档本身的属性为空 输出 {}

          ⚪ Comment,是一个特殊类型的NavigableString对象,其输出的内容不包括注释符号。

          1. print(soup.b) # 输出 Extremely bold
          2. print(soup.b.string) # 输出 Extremely bold
          3. print(type(soup.b.string)) # 输出

          3. find_all()搜索文档树

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

          ⚪  参数name :查找所有名字为name的tag,字符串对象会被自动忽略掉。

        • Foo
        • Bar
        • '''
        • soup = BeautifulSoup(html,'lxml')
        • # 查找与字符串完整匹配的内容
        • a_list = soup.find_all('a')
        • print(a_list)
        • # 返回所有表示和标签
        • for tag in soup.find_all(re.compile('^b')):
        • print(tag.name)
        • # 返回所有
        • 显示结果:

          1. body
          2. PS E:\1_tempFile\1_learn_code\VSCode\python_test> & D:/IDE/Python/python.exe e:/1_tempFile/1_learn_code/VSCode/python_test/python_beautifulsoup4/read_html.py
          3. body
          4. [
              "list" id="list-1" name="element">
          5. "element">Foo
          6. "element">Bar
          7. "element">Jay
          8. ,
              "list list-small" id="list-2">
          9. "element">Foo
          10. "element">Bar

          ⚪  参数kwargs :可以以标签=值的方式查找所有该标签下的内容。

          1. from bs4 import BeautifulSoup
          2. soup = BeautifulSoup(open('test.html'),'lxml')
          3. print(soup.find_all(id='list-1'))

          显示结果:

          1. [<ul class="list" id="list-1" name="element">
          2. <li class="element">Fooli>
          3. <li class="element">Barli>
          4. <li class="element">Jayli>
          5. ul>]

          ⚪ 参数text:通过text参数可以搜索文档中的字符串内容,于name参数的可选值一样,text参数接受字符串,正则表达式、列表。

          1. soup = BeautifulSoup(open('test.html'),'lxml')
          2. # 匹配字符串
          3. print(soup.find_all(text='a'))
          4. # 匹配正则表达式
          5. print(soup.find_all(text=re.compile('^b')))
          6. # 匹配列表
          7. print(soup.find_all(text=['ui','li']))

          4. CSS选择器

        • 在使用BeautifulSoup解析库时,经常结合CSS选择器来提取数据。

          ⚪ 根据标签名查找:比如传递 li 就会选择所有 li 标签

          1. soup = BeautifulSoup(open('test.html'),'lxml')
          2. print(soup.select('li'))

          显示结果:

          [<li class="element">Fooli>, <li class="element">Barli>, <li class="element">Jayli>, <li class="element">Fooli>, <li class="element">Barli>]

          ⚪ 根据类名class查找:.line  表示选择class="line"的所有标签。用 . 代表class。

          1. soup = BeautifulSoup(open('test.html'),'lxml')
          2. print(soup.select('.panel-heading'))

          显示结果:

          1. [<div class="panel-heading">
          2. <h4>Helloh4>
          3. div>]

          ⚪ 根据id查找:#box 表示选取id=box的所有标签,#代表id

          1. soup = BeautifulSoup(open('test.html'),'lxml')
          2. print(soup.select('#list-1'))

          显示结果:

          1. [<ul class="list" id="list-1" name="element">
          2. <li class="element">Fooli>
          3. <li class="element">Barli>
          4. <li class="element">Jayli>
          5. ul>]

          ⚪ 根据属性的名字查找:class和id分别使用 . 和#代表它们。其它的属性可以按照 input[name="username"]的格式查找 name="username"的标签。

          1. soup = BeautifulSoup(open('test.html'),'lxml')
          2. print(soup.select('ul[name="element"]'))

          显示结果:

          1. [<ul class="list" id="list-1" name="element">
          2. <li class="element">Fooli>
          3. <li class="element">Barli>
          4. <li class="element">Jayli>
          5. ul>]

          ⚪ 标签+类名或id的形式

          1. soup = BeautifulSoup(open('test.html'),'lxml')
          2. print(soup.select('ul#list-1'))
          3. # 查找id为list-1的ul标签
          4. print('='*40)
          5. # 查找class为list的ul标签
          6. print(soup.select('ul.list'))

          显示结果:

          1. [<ul class="list" id="list-1" name="element">
          2. <li class="element">Fooli>
          3. <li class="element">Barli>
          4. <li class="element">Jayli>
          5. ul>]
          6. ========================================
          7. [<ul class="list" id="list-1" name="element">
          8. <li class="element">Fooli>
          9. <li class="element">Barli>
          10. <li class="element">Jayli>
          11. ul>, <ul class="list list-small" id="list-2">
          12. <li class="element">Fooli>
          13. <a href="https://www.baidu.com">Baidua>
          14. <li class="element">Barli>
          15. ul>]
          16. Process finished with exit code 0

          ⚪ 查找直接子元素

          1. soup = BeautifulSoup(open('test.html'),'lxml')
          2. # 查找id="list-1"的标签下的直接子标签li
          3. print(soup.select('#list-1>li'))

          ⚪ 查找子孙标签

          1. soup = BeautifulSoup(open('test.html'),'lxml')
          2. # .panel_body 与 li之间是空格,表示查找class=panel_body的标签下的子标签或孙标签li
          3. print(soup.select('.panel_body li'))

          显示结果:

          [<li class="element">Fooli>, <li class="element">Barli>, <li class="element">Jayli>, <li class="element">Fooli>, <li class="element">Barli>]

          ⚪ 获取某个标签的属性

          1. soup = BeautifulSoup(open('test.html'),'lxml')
          2. # 先获取到
          3. div=soup.select('.panel_body')[0]
          4. # 再获取a标签下的href属性
          5. print(div.select('a')[0]['href'])

          显示结果:

          https://www.baidu.com

          ⚪ 获取文本内容

          ■ 使用string属性:获取某个标签下的文本内容,强调一个标签,不含嵌套内容,返回字符串

          1. soup = BeautifulSoup(open('test.html'),'lxml')
          2. # 先获取到
          3. div = soup.select('.panel_body')[0]
          4. # 再获取下面的标签下的内容

          显示结果:

          Baidu

          ■ 使用strings属性:获得某个标签下的所有文本内容,可以嵌套,返回一个生成器,可以用list转换为列表

          1. soup = BeautifulSoup(open('test.html'),'lxml')
          2. # 先获取到
          3. div = soup.select('.panel_body')[0]
          4. print(div.strings)
          5. print(list(div.strings))

          显示结果:

          1. <generator object Tag._all_strings at 0x000001BE4A405CF0>
          2. ['\n', '\n', 'Foo', '\n', 'Bar', '\n', 'Jay', '\n', '\n', '\n', 'Foo', '\n', 'Baidu', '\n', 'Bar', '\n', '\n']

          ■ 使用stripped_strings:和strings属性类似,不同在于stripped_strings会去掉字符串头部和尾部的空格和换行符

          1. soup = BeautifulSoup(open('test.html'),'lxml')
          2. # 先获取到
          3. div = soup.select('.panel_body')[0]
          4. print(div.stripped_strings)
          5. print(list(div.stripped_strings))

          显示结果:

          1. <generator object Tag.stripped_strings at 0x0000026D05935CF0>
          2. ['Foo', 'Bar', 'Jay', 'Foo', 'Baidu', 'Bar']

          ■ 使用get_text():获取所有字符串,包含嵌套,不过会把所有字符串拼接为一个再返回。

          1. soup = BeautifulSoup(open('test.html'),'lxml')
          2. # 先获取到
          3. div = soup.select('.panel_body')[0]
          4. print(div.get_text())

          显示结果:

          1. Foo
          2. Bar
          3. Jay
          4. Foo
          5. Baidu
          6. Bar

          全文参考:100天精通Python(爬虫篇)——第46天:爬虫解析器BeautifulSoup4_无 羡ღ的博客-CSDN博客一、BeautifulSoup4库介绍 1. 介绍 2. 下载模块 3. 解析库二、上手操作 1. 基础操作 2. 对象种类 3. 搜索文档树 4. css选择器https://blog.csdn.net/yuan2019035055/article/details/125695337

        • 相关阅读:
          通过platform实现
          【长文】带你搞明白Redis
          使用 L293D 电机驱动器 IC 和 Arduino 控制直流电机
          类和对象!
          电压和电流反馈判别及例子,绝对让你通透,其实也没有那么难,一次就看懂!从此终于搞懂了电压反馈和电流反馈!
          算法练习5——多数元素
          从基础知识到应用实例,一站式掌握 Python 正则表达式
          JAVA面向对象三大特征
          python使用字典暴力解析wifi密码
          vue3--响应式原理
        • 原文地址:https://blog.csdn.net/sinat_41752325/article/details/126444246