BeautifulSoup模块

2024-04-22 11:52
文章标签 模块 beautifulsoup

本文主要是介绍BeautifulSoup模块,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

【一】Beautifulsoup4初始

【前言】bs4模块

  • 安装

pip install beautifulsoup4

【1】什么是beautifulsoup:

​ 是一个可以从HTML或XML文件中提取数据的Python库。它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式。(官方)

​ beautifulsoup是一个解析器,可以特定的解析出内容,省去了我们编写正则表达式的麻烦。

  • 模块介绍

BeautifulSoup是一个解析库,可以从HTLML中提取数据的库

【2】HTML解析器

【1】内置解析器html.parser

  • Beautiful Soup支持Python标准库中的HTML解析器,还支持一些第三方的解析器
  • 如果我们不安装它,则 Python 会使用 Python默认的解析器
soup=BeautifulSoup(页面源码,'html.parser') 

【2】第三方解析器lxml

  • lxml 解析器更加强大,速度更快,推荐安装。
pip3 install lxml
  • 语法
soup=BeautifulSoup(页面源码,'lxml') 

【3】第三方解析器html5lib

  • 另一个可供选择的解析器是纯Python实现的 html5lib
  • html5lib的解析方式与浏览器相同
  • 可以选择下列方法来安装html5lib
pip3 install html5lib
  • 语法
soup=BeautifulSoup(页面源码,'html5lib') 

【4】解析器对比

(1)解析器优缺点

1

(2)解析器使用方法
解析器使用方法优势劣势
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语言库
html5libBeautifulSoup(markup, "html5lib")最好的容错性 以浏览器的方式解析文档 生成HTML5格式的文档速度慢 不依赖外部扩展

【3】生成soup对象

  • 从一个soup对象开始,以下两种方式生成一个soup对象

  • soup=beautifulsoup(解析内容,解析器)

  • 常用解析器:html.parser,lxml,xml,html5lib

  • 有时候需要安装安装解析器:比如pip3 install lxml

【1】方法一

from bs4 import BeautifulSoup# 指定HTML源码文件,传入文件源码
soup = BeautifulSoup(open("index.html"))   

【2】方法二

from bs4 import BeautifulSoup# 直接放入 HTML 源码
soup = BeautifulSoup("<html>data</html>")  

【3】示例

生成 BeautifulSoup 对象有两种常用的方法:

通过解析器直接解析字符串或文件内容:

from bs4 import BeautifulSoup# 通过字符串生成soup对象
html_content = "<html><body><h1>Hello, World!</h1><p>This is an example paragraph.</p></body></html>"
soup = BeautifulSoup(html_content, 'html.parser')# 通过文件生成soup对象
with open("example.html") as file:soup = BeautifulSoup(file, 'html.parser')

通过请求库获取网页内容并解析:

import requests
res = requests.get('https://www.biqg.cc/book/3525/', timeout=3)headers = {"User-Agent": UserAgent().random
}
# 指定HTML源码文件,传入文件源码
soup = BeautifulSoup(res.text, 'html.parser')
  • 使用标签名来获取结点:

soup.标签名

  • 使用标签名来获取结点标签名(这个重点是name,主要用于非标签名式筛选时,获取结果的标签名):

soup.标签.name

  • 使用标签名来获取结点属性:

soup.标签.attrs(获取全部属性)

soup.标签.attrs[属性名](获取指定属性)

soup.标签[属性名](获取指定属性)

soup.标签.get(属性名)

  • 使用标签名来获取结点的文本内容:

soup.标签.text

soup.标签.string

soup.标签.get_text()

补充1:

上面的筛选方式可以使用嵌套:

print(soup.p.a)#p标签下的a标签

# 获取源码中所有的文本内容
text = soup.get_text() 
# 获取源码中所有的a标签
a_tag = soup.find_all('a')
# 遍历每一个a标签
for a in a_tag:# 提取每一个a标签中的 href 属性a_href = a.get("href")

【二】文档树操作

【1】什么是文档树

​ BeautifulSoup的文档树是指使用BeautifulSoup解析HTML或XML文档后所构建的数据结构,它代表了整个文档的层级结构和内容关系。在BeautifulSoup中,文档树以特定的方式组织了文档中的各个元素(标签、文本、注释等),使得用户可以方便地对文档进行遍历、搜索和操作。

image-20240329110839808

【2】常见的文档树遍历算法

  • 选择起始节点:
    • 首先需要确定遍历的起始节点,可以是整个文档的根节点,也可以是某个指定的节点。
  • 访问当前节点:
    • 从起始节点开始,首先访问当前节点,可以获取当前节点的标签名、属性、文本内容等信息。
  • 处理当前节点:
    • 根据需要,对当前节点进行一些处理操作,比如判断节点类型、执行特定的任务等。
  • 遍历子节点:
    • 如果当前节点有子节点,将从第一个子节点开始递归遍历,重复步骤2和步骤3。
  • 遍历兄弟节点:
    • 如果当前节点没有子节点或者子节点已经遍历完毕,将继续遍历当前节点的下一个兄弟节点,重复步骤2和步骤3。
  • 返回父节点:
    • 当遍历到某个节点的兄弟节点都被遍历完毕后,返回到该节点的父节点,并继续遍历父节点的下一个兄弟节点。
  • 结束条件:
    • 当整个文档树的节点都被遍历完毕,或者满足某个结束条件时,结束遍历过程。

总结

​ 深度优先搜索(DFS)和广度优先搜索(BFS)。这两种搜索算法在处理文档树时具有不同的特点和应用场景:

  1. 深度优先搜索(DFS):
    • 从起始节点开始,尽可能深地访问每个节点的子节点,直到到达最深层的节点。
    • 使用递归或栈来实现,适合于需要优先探索整棵子树的情况。
    • 对于HTML/XML文档DOM树,DFS可以帮助我们深入到每个节点的子节点,适用于深度优先遍历和搜索。
  2. 广度优先搜索(BFS):
    • 从起始节点开始,按层级顺序逐层访问各个节点,先访问完当前层的所有节点,再逐层向下遍历。
    • 使用队列来实现,适合于需要逐层扩展搜索范围的情况。
    • 在处理HTML/XML文档DOM树时,BFS可以帮助我们逐层遍历节点,适用于广度优先遍历和搜索。

​ 选择DFS还是BFS取决于具体的需求和应用场景。DFS适合于深入探索子树,而BFS适合于逐层扩展搜索范围。

from bs4 import BeautifulSoup
html = """
<html >
<head>
<meta charset="UTF-8">
<title>this is a title</title>
</head>
<body>
<p class="news">123</p>
<p class="contents" id="i1">456</p>
<a href="http://www.baidu.com" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >advertisements</a>
</body>
</html>
"""
soup = BeautifulSoup(html,'lxml')
print("获取结点".center(50,'-'))
print(soup.head)#获取head标签
print(soup.p)#返回第一个p标签
#获取结点名
print("获取结点名".center(50,'-'))
print(soup.head.name)
print(soup.find(id='i1').name)
#获取文本内容
print("获取文本内容".center(50,'-'))
print(soup.title.string)#返回title的内容
print(soup.title.text)#返回title的内容
print(soup.title.get_text())
#获取属性
print("-----获取属性-----")
print(soup.p.attrs)#以字典形式返回标签的内容
print(soup.p.attrs['class'])#以列表形式返回标签的值
print(soup.p['class'])#以列表形式返回标签的值
print(soup.p.get('class'))#############
t=soup.title
print(type(t))#<class 'bs4.element.Tag'>
print(t.name)#title
print(t.text)#嵌套选择:
print(soup.head.title.string)

【5】遍历文档树的语法:

  1. 子节点和子孙节点的遍历:
    • 使用.contents可以获取子节点列表,例如:soup.body.contents
    • 使用.children可以获取子节点的迭代器,例如:for child in soup.body.children:
    • 使用.descendants可以递归获取所有子孙节点,例如:for descendant in soup.body.descendants:
  2. 父节点和祖先节点的遍历:
    • 使用.parent可以获取父节点,例如:soup.title.parent
    • 使用.parents可以获取所有祖先节点,例如:for parent in soup.title.parents:
  3. 兄弟节点的遍历:
    • 使用.next_sibling.previous_sibling可以获取下一个兄弟节点和上一个兄弟节点。
    • 使用.next_siblings.previous_siblings可以获取所有后续兄弟节点和前序兄弟节点。
  4. 查找特定节点:
    • 使用.find()可以查找符合条件的第一个节点,例如:soup.find('p', class_='news')
    • 使用.find_all()可以查找符合条件的所有节点,例如:soup.find_all('p')
  5. CSS选择器:
    • 使用类似CSS选择器的语法来查找节点,例如:soup.select('p.contents')

【6】遍历文档树

直接通过标签名字选择,特点是速度快,但是如果存在多个相同的标签则只返回第一个

  • html文档准备
html_doc = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p id="my_p" class="title">hello<b id="bbb" class="boldest">The Dormouse's story</b>
</p><p class="story">Once upon a time there were three little sisters; and their names were
<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>;
and they lived at the bottom of a well.</p><p class="story">...</p>
"""
  • 文档容错能力,不是一个标准的html也能解析
# 上述html文档的html body标签并没有闭合
soup=BeautifulSoup(html_doc,'lxml')
  • 遍历文档树用法

获取标签内的数据

head = soup.head (head是标签对象)
print(head)

获取标签名称

print(head.name)

获取标签的属性,属性可能有多个,放在列表中

p = soup.body.p # 获取body标签下的p标签
print(p.attrs)  # 获取p标签的属性/id等
print(p.attrs.get('class'))  # 获取p标签的属性方式一,得到的结果是一个列表
print(p.get('class'))  # 获取p标签的属性方式方式二,得到的结果是一个列表
print(p['class'])  # 获取p标签的属性方式方式二,得到的结果是一个列表

嵌套选择

a=soup.body.a
print(a.get('id'))
# 子节点、子孙节点
print(soup.p.contents) #p下所有子节点
print(soup.p.children) #得到一个迭代器,包含p下所有子节点
print(list(soup.p.children)) #得到一个迭代器,包含p下所有子节点
# 父节点、祖先节点
print(soup.a.parent) #获取a标签的父节点(只有一个)
print(soup.p.parent) #获取p标签的父节点
print(soup.a.parents) #找到a标签所有的祖先节点,父亲的父亲,父亲的父亲的父亲...
print(list(soup.a.parents))#找到a标签所有的祖先节点,父亲的父亲,父亲的父亲的父亲...
print(len(list(soup.a.parents)))#找到a标签所有的祖先节点,父亲的父亲,父亲的父亲的父亲...
# 兄弟节点
print(soup.a.next_sibling) #下一个兄弟
print(soup.a.previous_sibling) #上一个兄弟print(list(soup.a.next_siblings)) #下面的兄弟们=>生成器对象
print(list(soup.a.previous_siblings)) #上面的兄弟们=>生成器对象

【7】搜索文档树

【1】 find_all

find():只返回找到的第一个

find_all():找到的所有

find_all() 方法的用法如下:

  • soup.find_all(name, attrs, recursive, text, limit, **kwargs)
    

    :根据给定的条件查找符合条件的所有元素。

    • name:指定要查找的标签名称。
    • attrs:以字典形式指定要查找的标签的属性和属性值。
    • recursive:指定是否递归搜索子孙节点,默认为 True。
    • text:指定要搜索的文本内容。
    • limit:限制返回结果的数量。
    • **kwargs:其他关键字参数,用于匹配标签的其他属性。
  1. 通过标签名搜索:

    soup.find_all('a')  # 查找所有的<a>标签
    soup.find('div')     # 查找第一个<div>标签
    
  2. 通过CSS类名搜索:

    soup.find_all(class_='class_name')soup.find_all(class_='header wap_none')
    # 查找所有具有指定类名的标签
    
  3. 通过id搜索:

    soup.find_all(id='element_id')  # 目标地址
    res = requests.get('https://so.gushiwen.cn/gushi/tangshi.aspx')
    # HTML文本进行解析,创建一个BeautifulSoup对象soup
    soup = BeautifulSoup(res.text, 'html.parser')
    # 查找所有id为'arc-body'的标签
    ids = soup.find_all(id='threeWeixin2')
    print(ids)
    # 查找所有具有指定id的标签
    
  4. 通过属性值搜索:

    soup.find_all(attrs={'attribute_name': 'value'})  # 查找所有具有指定属性值的标签a = soup.find_all('div', attrs={'class': 'book'})print(a)
    
  5. 通过文本内容搜索:

    soup.find_all(text='some text')  # 查找所有包含指定文本内容的标签
    

【2】find

  • find() 方法用于在文档中查找符合条件的tag,并返回第一个匹配的结果。
  • 它可以通过指定name、attrs、recursive和string等参数来过滤查找结果。
find( name , attrs , recursive , string , **kwargs )
  • name: 指定要查找的tag名称,可以是字符串或正则表达式。
  • attrs: 指定tag的属性,可以是字典或字典的列表。
  • recursive: 指定是否递归查找子孙tag,默认为True。
  • string: 指定查找的文本内容,可以是字符串或正则表达式。

【3】find_all()find() 的区别

find_all()find() 都是 BeautifulSoup 中用于查找节点的方法,它们之间的区别在于:

  1. find_all(): 用于查找符合条件的所有节点,并以列表形式返回结果。
  2. find(): 用于查找符合条件的第一个节点,并直接返回该节点对象。
  • 唯一的区别是
    • find_all() 方法的返回结果是值包含一个元素的列表
      • find() 方法直接返回结果
      • find_all() 方法没有找到目标是返回空列表
        • find() 方法找不到目标时,返回 None

【4】五种过滤器

  • 字符串过滤:过滤内容是字符串
a = soup.find(name='a')
print(a) # <a class="

这篇关于BeautifulSoup模块的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/925704

相关文章

python: 多模块(.py)中全局变量的导入

文章目录 global关键字可变类型和不可变类型数据的内存地址单模块(单个py文件)的全局变量示例总结 多模块(多个py文件)的全局变量from x import x导入全局变量示例 import x导入全局变量示例 总结 global关键字 global 的作用范围是模块(.py)级别: 当你在一个模块(文件)中使用 global 声明变量时,这个变量只在该模块的全局命名空

深入探索协同过滤:从原理到推荐模块案例

文章目录 前言一、协同过滤1. 基于用户的协同过滤(UserCF)2. 基于物品的协同过滤(ItemCF)3. 相似度计算方法 二、相似度计算方法1. 欧氏距离2. 皮尔逊相关系数3. 杰卡德相似系数4. 余弦相似度 三、推荐模块案例1.基于文章的协同过滤推荐功能2.基于用户的协同过滤推荐功能 前言     在信息过载的时代,推荐系统成为连接用户与内容的桥梁。本文聚焦于

Python3 BeautifulSoup爬虫 POJ自动提交

POJ 提交代码采用Base64加密方式 import http.cookiejarimport loggingimport urllib.parseimport urllib.requestimport base64from bs4 import BeautifulSoupfrom submitcode import SubmitCodeclass SubmitPoj():de

Jenkins构建Maven聚合工程,指定构建子模块

一、设置单独编译构建子模块 配置: 1、Root POM指向父pom.xml 2、Goals and options指定构建模块的参数: mvn -pl project1/project1-son -am clean package 单独构建project1-son项目以及它所依赖的其它项目。 说明: mvn clean package -pl 父级模块名/子模块名 -am参数

寻迹模块TCRT5000的应用原理和功能实现(基于STM32)

目录 概述 1 认识TCRT5000 1.1 模块介绍 1.2 电气特性 2 系统应用 2.1 系统架构 2.2 STM32Cube创建工程 3 功能实现 3.1 代码实现 3.2 源代码文件 4 功能测试 4.1 检测黑线状态 4.2 未检测黑线状态 概述 本文主要介绍TCRT5000模块的使用原理,包括该模块的硬件实现方式,电路实现原理,还使用STM32类

python内置模块datetime.time类详细介绍

​​​​​​​Python的datetime模块是一个强大的日期和时间处理库,它提供了多个类来处理日期和时间。主要包括几个功能类datetime.date、datetime.time、datetime.datetime、datetime.timedelta,datetime.timezone等。 ----------动动小手,非常感谢各位的点赞收藏和关注。----------- 使用datet

C8T6超绝模块--EXTI

C8T6超绝模块–EXTI 大纲 控制流程结构体分析EXTI实现按键 具体案例 控制流程 这里是流程框图,具体可以去看我STM32专栏的EXTI的具体分析 结构体分析 typedef struct {uint32_t EXTI_Line; // 中断/事件线EXTIMode_TypeDef EXTI_Mode; // EXTI 模式EXTITrigger_TypeDef EXTI_

1、创建多模块的maven springboot项目

现在的java的项目都是多模块的,这次也跟个风。 目标:实现下述结构 项目AcedBoot, 子模块:         aced-api 对外提供接口,         aced-web 给前端提供接口,         aced-service 服务层,         aced-dao 数据底层,包含数据库mapper和实体类entity,         aced-commo

Vue2电商项目(二) Home模块的开发;(还需要补充js节流和防抖的回顾链接)

文章目录 一、Home模块拆分1. 三级联动组件TypeNav2. 其余组件 二、发送请求的准备工作1. axios的二次封装2. 统一管理接口API----跨域3. nprogress进度条 三、 vuex模块开发四、TypeNav三级联动组件开发1. 动态展示三级联动数据2. 三级联动 动态背景(1)、方式一:CSS样式(2)、方式二:JS 3. 控制二三级数据隐藏与显示--绑定styl

PrestaShop免费模块/插件/扩展/工具下载

PrestaShop免费模块/插件/扩展/工具下载 PrestaShop免费模块 适用于您的电子商务网站的PrestaShop模块 现有超过3,000个PrestaShop模块可帮助您自定义在线商店,增加流量,提高转化率并建立客户忠诚度。 使您的电子商务网站成功! 下载(超过142+之多的PrestaShop官网认证的免费模块) 标签PrestaShop免费, PrestaShop免费工