Beautiful Soup4数据解析与提取

2023年 9月 12日 44.6k 0

Beautiful Soup4

概述

Beautiful Soup是一个Python的库,用于解析HTML和XML文档,提供了方便的数据提取和操作功能。它可以帮助从网页中提取所需的数据,例如标签、文本内容、属性等。

Beautiful Soup会自动将输入文档转换为Unicode编码,输出文档转换为utf-8编码。

Beautiful Soup用来解析 HTML比较简单,API非常人性化,支持多种解析器。

文档:https://beautifulsoup.readthedocs.io/zh_CN/v4.4.0/

文档:https://www.crummy.com/software/BeautifulSoup/bs4/doc.zh/

主要特点

灵活的解析方式:

Beautiful Soup支持多种解析器,包括Python标准库中的html.parser解析器,以及第三方库lxml和html5lib。这样,我们可以根据需要选择合适的解析器进行处理。

简单直观的API:

Beautiful Soup提供了简洁而友好的API,使得解析HTML文档变得非常容易。我们可以使用简洁的方法来选择特定的标签、获取标签中的文本内容、提取属性值等。

强大的文档遍历能力:

通过Beautiful Soup,我们可以遍历整个HTML文档树,访问、修改或删除各个节点,甚至可以通过嵌套选择器,快速地定位到需要的节点。

对破碎HTML的容错处理:

Beautiful Soup能够处理破碎的HTML文档,例如自动纠正未闭合的标签、自动添加缺失的标签等,使得提取数据更加稳定和可靠。

解析器

Beautiful在解析时依赖解析器,它除了支持Python标准库中的HTML解析器外,还支持一些第三方库。

支持的解析器:

解析器 使用方法 优势 劣势
Python标准库 BeautifulSoup(markup, "html.parser") Python的内置标准库 执行速度适中 文档容错能力强 Python 2.7.3 or 3.2.2)前 的版本中文档容错能力差
lxml HTML 解析器 BeautifulSoup(markup, "lxml") 速度快 文档容错能力强 需要安装C语言库
lxml XML 解析器 BeautifulSoup(markup, ["lxml-xml"]) BeautifulSoup(markup, "xml") 速度快 唯一支持XML的解析器 需要安装C语言库
html5lib BeautifulSoup(markup, "html5lib") 最好的容错性 以浏览器的方式解析文档 生成HTML5格式的文档 速度慢 不依赖外部扩展

由此可见:

lxml解析器可以解析HTML和XML文档,并且速度快,容错能力强,所有推荐使用它。如果使用lxml,那么在初始化的BeautifulSoup时候,把第二个参数设为lxml即可。

Beautiful Soup4的基本使用

安装库

pip install beautifulsoup4

pip install lxml

创建HTML文件

将一段文档传入BeautifulSoup 的构造方法,就能得到一个文档的对象, 可以传入一段字符串或一个文件。

这里创建一个test.html文件,以此创建一个文档对象。




    
    Title



    
  • H1
  • H2
  • H3

基本用法

# 导入模块
from bs4 import BeautifulSoup

# 创建 beautifulsoup对象,有2种方式创建
# 1.通过字符串创建, 第二个参数用于指定解析器
# soup = BeautifulSoup("html", 'lxml')
# 2.通过文件创建
soup = BeautifulSoup(open('test.html'), 'lxml')
# 打印输出
# print(soup.prettify())


# 获取元素标签元素,默认返回第一个元素
print(soup.li)

# 使用 .contents 或 .children 获取子元素
# 返回列表
print(soup.ul.contents)
# 返回迭代器
print(soup.li.children)

# 获取元素内容
print(soup.title.get_text())

# 获取元素属性值,默认取第一个元素属性值
print(soup.li.get('class'))

操作结果如下:

  • H1
  • ['\n',
  • H1
  • , '\n',
  • H2
  • , '\n',
  • H3
  • , '\n'] Title ['class01']

    Beautiful Soup4的对象种类

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

    Tag对象

    在Beautiful Soup中,Tag对象是用于表示HTML或XML文档中的标签元素的对象,Tag对象与原生文档中的tag相同。Tag对象包含了标签元素的名称、属性和内容等信息,并提供了多种方法来获取、修改和操作这些信息。

    soup = BeautifulSoup('Extremely bold')
    tag = soup.b
    type(tag)
    # 
    

    常用的Tag对象的属性和方法

    属性 描述 示例
    name属性 获取标签的名称 tag_name = tag.name
    string属性 获取标签内的文本内容 tag_text = tag.string
    attrs属性 获取标签的属性,以字典的形式返回 tag_attrs = tag.attrs
    get()方法 根据属性名获取标签的属性值 attr_value = tag.get('attribute_name')
    find()方法 查找并返回第一个满足条件的子标签元素 child_tag = tag.find('tag_name')
    find_all()方法 查找并返回所有满足条件的子标签元素,以列表的形式返回 child_tags = tag.find_all('tag_name')
    parent属性 获取当前标签的父标签 parent_tag = tag.parent
    parents属性 获取当前标签的所有祖先标签,以生成器的形式返回 for parent in tag.parents: print(parent)
    children属性 获取当前标签的直接子标签,以生成器的形式返回 for child in tag.children: print(child)
    next_sibling属性 获取当前标签的下一个兄弟标签 next_sibling_tag = tag.next_sibling
    previous_sibling属性 获取当前标签的上一个兄弟标签 previous_sibling_tag = tag.previous_sibling

    NavigableString对象

    NavigableString对象是Beautiful Soup库中的一种数据类型,用于表示在HTML或XML文档中的纯文本内容。它继承自Python的基本字符串类型,但具有额外的功能和特性,使其适用于处理文档中的文本内容。

    假设有如下HTML代码片段:

    This is a beautiful day.

    使用Beautiful Soup将其解析为一个文档对象:

    from bs4 import BeautifulSoup
    
    html = '

    This is a beautiful day.

    ' soup = BeautifulSoup(html, 'html.parser')

    获取

    标签的内容,这实际上是一个NavigableString对象:

    p_tag = soup.find('p')
    content = p_tag.string
    print(content)  # 输出:This is a
    print(type(content))  # 输出:
    

    还可以对NavigableString对象进行一些操作,如获取文本内容、替换文本以及去除空白字符:

    # 获取文本内容
    text = content.strip()
    print(text)  # 输出:This is a
    
    # 替换文本
    p_tag.string.replace_with('Hello')
    print(p_tag)  # 输出:

    Hellobeautiful day.

    # 去除空白字符 text_without_spaces = p_tag.string.strip() print(text_without_spaces) # 输出:Hello
    属性 描述 示例
    string属性 用于获取NavigableString对象的文本内容 text = navigable_string.string
    replace_with()方法 用于用另一个字符串或对象替换当前NavigableString对象 navigable_string.replace_with(new_string)
    strip()方法 去除字符串两端的空白字符 stripped_text = navigable_string.strip()
    parent属性 获取NavigableString对象所属的父节点(通常是一个Tag对象) parent_tag = navigable_string.parent
    next_sibling属性 获取NavigableString对象的下一个兄弟节点 next_sibling = navigable_string.next_sibling
    previous_sibling属性 获取NavigableString对象的上一个兄弟节点 previous_sibling = navigable_string.previous_sibling

    BeautifulSoup对象

    BeautifulSoup对象是Beautiful Soup库的核心对象,用于解析和遍历HTML或XML文档。

    常用方法:

    find(name, attrs, recursive, string, **kwargs):根据指定的标签名、属性、文本内容等查找第一个匹配的标签
    
    find_all(name, attrs, recursive, string, limit, **kwargs): 根据指定的标签名、属性、文本内容等查找所有匹配的标签,并返回一个列表
    
    select(css_selector): 使用CSS选择器语法查找匹配的标签,并返回一个列表
    
    prettify():以美观的方式输出整个文档的内容,包括标签、文本和缩进
    
    has_attr(name):检查当前标签是否具有指定的属性名,返回布尔值
    
    get_text():获取当前标签和所有子标签的文本内容,并返回一个字符串
    

    常用属性:

    soup.title:获取文档中第一个标签的内容
    
    soup.head:获取文档中的标签
    
    soup.body:获取文档中的标签
    
    soup.find_all('tag'):获取文档中所有匹配的标签,并返回一个列表
    
    soup.text:获取整个文档中的纯文本内容(去除标签等)
    

    Comment对象

    Comment对象是Beautiful Soup库中的一种特殊类型的对象,用于表示HTML或XML文档中的注释内容。

    在解析HTML或XML文档时,Beautiful Soup将注释内容作为Comment对象来表示。注释是文档中的一种特殊元素,用于添加注解、说明或暂时删除一部分内容。Comment对象可以通过Beautiful Soup库的解析器自动识别和处理。

    处理和访问HTML文档中的注释内容示例:

    from bs4 import BeautifulSoup
    
    # 创建包含注释的HTML字符串
    html = " 

    Hello, World!

    " # 解析HTML文档 soup = BeautifulSoup(html, 'html.parser') # 使用type()函数获取注释对象的类型 comment = soup.body.next_sibling print(type(comment)) # 输出 # 使用`.string`属性获取注释内容 comment_content = comment.string print(comment_content) # 输出 This is a comment

    搜索文档树

    Beautiful Soup提供了多种方式来查找和定位HTML文档中的元素。

    方法选择器

    使用Beautiful Soup的find()或find_all()方法可以通过标签名、结合属性名和属性值、结合文本内容等方式来选择元素。

    两者区别:

    find返回符合条件的第一个元素
    
    find_all返回符合条件的所有元素列表
    

    例如:soup.find('div')会返回第一个div标签的元素,soup.find_all('a')会返回所有的a标签元素。

    1.通过标签或标签列表查找元素

    # 查找第一个div标签的元素
    soup.find('div')
    
    # 查找所有的a标签元素
    soup.find_all('a')
    
    # 查找所有li标签
    soup.find_all('li')
    
    # 查找所有a标签和b标签
    soup.find_all(['a','b'])
    

    2.通过正则表达式查找元素

    # 以sp开头的标签查找
    import re
    print(soup.find_all(re.compile("^sp")))
    

    3.通过属性查找元素

    find = soup.find_all(
        attrs={
             "属性名":"值"
        }
    )
    print(find)
    
    # 查找第一个具有href属性的a标签元素
    soup.find('a', href=True)
    
    # 查找所有具有class属性的div标签元素
    soup.find_all('div', class_=True)
    

    4.通过文本内容查找元素

    # 查找第一个包含"Hello"文本内容的元素
    soup.find(text='Hello')
    
    # 查找所有包含"World"文本内容的元素
    soup.find_all(text="World")
    

    5.通过关键词参数查找元素

    soup.find_all(id='id01')
    

    6.混合使用

    soup.find_all(
     '标签名',
     attrs={
       "属性名":"值"
     },
     text="内容"
    )
    

    CSS选择器

    使用Beautiful Soup的select()方法可以通过CSS选择器来查找元素。CSS选择器是一种强大而灵活的方式,可以根据标签名、类名、ID、属性以及它们的组合来定位元素。

    1.类选择器

    通过类名查找元素,使用.符号加上类名来查找元素

    soup.select('.className')
    

    2.ID选择器

    通过ID查找元素,使用#符号加上ID来查找元素

    soup.select('#id')
    

    3.标签选择器

    通过标签名查找元素,直接使用标签名来查找元素

    soup.select('p')
    

    4.属性选择器

    通过属性查找元素:可以使用[属性名=属性值]的格式来查找具有特定属性及属性值的元素

    soup.select('[属性="值"]')
    
    soup.select('[href="https://juejin.cn/post/example.com"]')
    
    soup.select('a[href="http://baidu.com"]')
    

    5.组合选择器

    可以将多个选择器组合在一起以获得更精确的查找

    # 返回所有在具有特定类名的div元素内的a标签元素
    soup.select('div.class01 a')
    
    soup.select('div a')
    
    

    关联选择

    在进行元素查找的过程中,有时候不能做到一步就获取到想要的节点元素,需要选取某一个节点元素,然后以这个节点为基准再选取它的子节点、父节点、兄弟节点等。

    在Beautiful Soup中,可以通过使用CSS选择器语法来进行关联选择,需要借助Beautiful Soup的select()方法,它允许使用CSS选择器来选择元素。

    1.后代选择器(空格):可以选择指定元素下的所有后代元素。

    div a               /* 选择div元素下的所有a元素 */
    
    .container p        /* 选择类名为container的元素下的所有p元素 */
    

    2.直接子代选择器(>):可以选择指定元素的直接子代元素。

    div > a             /* 选择div元素的直接子代的a元素 */
    
    .container > p      /* 选择类名为container的元素的直接子代的p元素 */
    

    3.相邻兄弟选择器(+):可以选择与指定元素紧邻的下一个同级元素。

    h1 + p              /* 选择紧接在h1元素后的同级p元素 */
    
    .container + p      /* 选择紧接在类名为container的元素后的同级p元素 */
    

    4.通用兄弟选择器(~):可以选择与指定元素同级的所有后续元素。

    h1 ~ p              /* 选择与h1元素同级的所有p元素 */
    
    .container ~ p      /* 选择与类名为container的元素同级的所有p元素 */
    

    5.混合选择器:可以结合多个不同类型的选择器来选择特定的元素

    div , p   /* 选择所有div元素和所有p元素 */
    
    .cls1.cls2     /*  选择类名是cls1并且类名是cls2 */
    

    遍历文档树

    在Beautiful Soup中,遍历文档树是一种常见的操作,用于访问和处理HTML或XML文档的各个节点

    标签的子节点和父节点

    contents:获取Tag的所有子节点,返回一个list

    print(bs.tag.contents)
    # 使用列表索引获取某一个元素
    print(bs.tag.contents[1])
    

    children:获取Tag的所有子节点,返回一个生成器

    for child in tag.contents:
        print(child)
    

    parent属性获取标签的父节点

    parent_tag = tag.parent
    

    标签的同级兄弟节点

    可以使用.next_sibling和.previous_sibling属性获取标签的下一个或上一个同级兄弟节点。

    next_sibling = tag.next_sibling
    previous_sibling = tag.previous_sibling
    

    递归遍历文档树

    可以使用.find()和.find_all()方法在文档树中递归搜索匹配的标签。

    可以使用.descendants生成器迭代器遍历文档树的所有子孙节点。

    for tag in soup.find_all('a'):
        print(tag)
    
    for descendant in tag.descendants:
        print(descendant)
    

    遍历标签属性

    可以使用.attrs属性获取标签的所有属性,并遍历它们。

    for attr in tag.attrs:
        print(attr)
    

    相关文章

    JavaScript2024新功能:Object.groupBy、正则表达式v标志
    PHP trim 函数对多字节字符的使用和限制
    新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
    使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
    为React 19做准备:WordPress 6.6用户指南
    如何删除WordPress中的所有评论

    发布评论