【Python】BeautifulSoup:HTML解析

news/2024/9/17 3:19:05/ 标签: python, beautifulsoup, html

BeautifulSoup 是 Python 中用于解析和处理 HTML 或 XML 文档的强大库。它提供了简洁的接口,能高效处理复杂的网页结构,非常适合网页爬虫和数据提取任务。本文将详细介绍如何使用 BeautifulSoup 进行 HTML 文档的解析与操作。

BeautifulSoup 对象

BeautifulSoup 是进入 HTML 解析的核心工具。它将 HTML 或 XML 字符串转换为可操作的文档树,使用户可以方便地检索和修改网页内容。

创建 BeautifulSoup 对象

首先导入库并初始化 BeautifulSoup 对象。最常见的解析器包括:

  • html.parser:Python 内置的解析器,速度快且无需额外安装。
  • lxml:处理复杂 HTML 的功能更强大,但需要额外安装。
  • html5lib:完全遵循 HTML5 标准,容错性好,速度相对较慢。
html" title=python>python">from bs4 import BeautifulSouphtml_doc = "<html><head><title>示例页面</title></head><body><p>这是一个段落。</p></body></html>"
soup = BeautifulSoup(html_doc, 'html.parser')  # 使用内置的html.parser

格式化输出

使用 prettify() 方法可以将文档树格式化输出,以方便查看 HTML 结构:

html" title=python>python">print(soup.prettify())

核心元素介绍

BeautifulSoup 解析的文档由多个核心元素组成,如标签 (Tag)、属性 (Attributes) 和文本内容 (NavigableString)。理解这些基础概念对操作文档树至关重要。

标签(Tag)

标签是 BeautifulSoup 文档树的基本单元,表示 HTML 中的各个标签。可以通过标签名或 find() 方法检索特定的标签:

html" title=python>python">tag = soup.p  # 获取第一个 <p> 标签
print(tag)  # 输出:<p>这是一个段落。</p>

标签名(name)

每个标签都有 name 属性,表示标签的名称:

html" title=python>python">print(tag.name)  # 输出:p

属性(attrs)

每个标签的属性存储在 attrs 字典中,可以轻松获取或修改标签的属性:

html" title=python>python">print(tag.attrs)  # 输出:{}
tag['class'] = 'my-class'  # 修改 class 属性
print(tag['class'])  # 输出:my-class

文本内容(NavigableString)

标签内的文本部分用 NavigableString 对象表示,可以通过 tag.string 获取:

html" title=python>python">print(tag.string)  # 输出:这是一个段落。

注释(Comment)

HTML 中的注释会被解析为 Comment 对象:

html" title=python>python">html_with_comment = "<p><!--这是注释--></p>"
soup = BeautifulSoup(html_with_comment, 'html.parser')
comment = soup.p.string
print(type(comment))  # 输出:<class 'bs4.element.Comment'>

获取文本与属性

获取标签文本

使用 get_text() 方法可以提取标签内的所有文本内容:

  • 提取整个文档的文本
html" title=python>python">print(soup.get_text())
  • 提取特定标签的文本
html" title=python>python">print(soup.p.get_text())  # 输出:这是一个段落。

获取标签属性

可以通过 get() 方法获取标签的特定属性:

html" title=python>python">print(soup.a.get('href'))  # 获取 <a> 标签的 href 属性

文档树遍历

BeautifulSoup 提供了多种方式来遍历 HTML 文档树,可以轻松访问节点的子节点、父节点和兄弟节点。

下行遍历

  • contents:返回标签的直接子节点列表。
  • children:生成器,逐个访问子节点。
  • descendants:递归访问所有子孙节点。
html" title=python>python">for child in soup.body.children:print(child)

上行遍历

  • parent:获取标签的直接父节点。
  • parents:生成器,逐层返回祖先节点。
html" title=python>python">print(soup.p.parent)  # 输出父节点 <body>

平行遍历

  • next_sibling:获取下一个兄弟节点。
  • previous_sibling:获取上一个兄弟节点。
html" title=python>python">print(soup.p.next_sibling)  # 输出下一个兄弟节点

标签检索

find() 方法

find() 方法用于在HTML文档中查找第一个符合条件的标签。它可以通过标签名、属性、文本内容等条件进行查找。以下是 find() 方法的一些常用参数:

  • 标签名 (name): 指定要查找的标签名。

    html" title=python>python">p_tag = soup.find('p')  # 查找第一个 <p> 标签
    
  • 属性 (attrs): 指定要查找的标签属性,可以是字典形式或单独的属性名。

    html" title=python>python">link_tag = soup.find('a', href=True)  # 查找第一个具有 href 属性的 <a> 标签
    
  • 文本内容 (text): 查找标签中包含指定文本的标签。

    html" title=python>python">soup.find('p', text='Hello')  # 查找内容为 'Hello' 的第一个 <p> 标签。
    
  • 递归查找 (recursive): 布尔值,指定是否递归查找子标签,默认为 True

    html" title=python>python">soup.find('div', recursive=False)  # 查找第一个 <div> 标签,不包括子标签。
    

find_all() 方法

find_all() 方法用于查找所有符合条件的标签,并返回一个列表。它同样支持通过标签名、属性、文本内容等条件进行查找。以下是 find_all() 方法的一些常用参数:

  • 标签名 (name): 指定要查找的标签名。

    html" title=python>python">soup.find_all('p')  # 查找所有 <p> 标签。
    
  • 属性 (attrs): 指定要查找的标签属性,可以是字典形式。

    html" title=python>python">soup.find_all('a', class_='link')  # 查找所有 class 为 'link' 的 <a> 标签。
    
  • 文本内容 (text): 查找标签中包含指定文本的所有标签。

    html" title=python>python">soup.find_all('p', text='Hello')  # 查找所有内容为 'Hello' 的 <p> 标签。
    
  • 限制数量 (limit): 限制返回的标签数量。

    html" title=python>python">soup.find_all('p', limit=3)  # 查找前 3 个 <p> 标签。
    

select() 方法

select() 方法使用CSS选择器语法来查找元素,它支持更复杂的查询,并返回所有符合条件的标签列表。以下是 select() 方法的一些常用参数:

  • 选择器 (selector): 使用CSS选择器语法。

    html" title=python>python">soup.select('p')  # 查找所有 <p> 标签。
    
  • 属性 (attrs): 指定CSS选择器的属性筛选。

    html" title=python>python">soup.select('a[href]')  # 查找所有具有 href 属性的 `<a>` 标签。
    
  • 类名 (class_): 使用点(.)语法查找所有指定 class 的元素。

    html" title=python>python">soup.select('.class-name')  # 查找所有 class 为 'class-name' 的元素。
    
  • ID (id): 使用井号(#)语法查找具有特定 id 的元素。

    html" title=python>python">soup.select('#content')` 查找 id 为 `'content'` 的元素。
    
  • 复杂选择器: 可以组合使用选择器来查找特定条件下的标签。

    html" title=python>python">soup.select('div#content p.text')  # 查找 `id` 为 'content' 的 div 中所有 class 为 'text' 的 `<p>` 标签。
    

select() 方法非常灵活,能够执行复杂的查询,是处理HTML文档的强大工具。

修改文档树

使用 BeautifulSoup,HTML 文档可以轻松修改。

修改标签内容

使用 replace_with() 方法可以替换标签中的文本内容:

html" title=python>python">soup.p.string.replace_with("新的段落内容")
print(soup.p)

插入和删除标签

你可以通过 new_tag() 方法创建新的标签,并使用 append() 方法插入到文档树中:

html" title=python>python">new_tag = soup.new_tag("p")
new_tag.string = "新插入的段落"
soup.body.append(new_tag)
print(soup.body)

异常处理

解析器可能会出现不支持某些 HTML 特性的情况,建议使用 try...except 捕获解析器错误:

html" title=python>python">from bs4 import FeatureNotFoundtry:BeautifulSoup("<html></html>", "unsupported_parser")
except FeatureNotFound as e:print(f"解析器不支持: {e}")

http://www.ppmy.cn/news/1521438.html

相关文章

Go 语言知识点总结

在 Go 语言中&#xff0c;... 是用于定义可变参数&#xff08;variadic parameters&#xff09;的符号。 在 func sum(nums ...int) 中&#xff0c;nums ...int 表示函数 sum 可以接受任意数量的 int 类型的参数&#xff0c;传入的参数将被打包成一个切片 nums&#xff0c;将 …

硬件工程师笔试面试知识器件篇——电感

目录​​​​​​​ 3、电感 3.1、基础 电感原理图 电感实物图 3.1.1、定义与单位 1)定义: 2) 单位: 3.1.2、物理原理 1)法拉第电磁感应定律: 2)楞次定律: 3.1.3、电感器的构造 3.1.4、类型 3.1.5、应用 3.1.6、特性 3.1.7、设计考虑 3.2、相关问题 3.…

基于FCM模糊聚类算法的图像分割matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1 FCM算法原理 4.2 图像分割中的应用 5.算法完整程序工程 1.算法运行效果图预览 (完整程序运行后无水印) 2.算法运行软件版本 matlab2022a 3.部分核心程序 &#xff08;完整版代码包…

【嵌入式学习笔记】---- 通信基础

1 数据传输方式 按照数据传输的方式&#xff0c;通信可以分为串行通信和并行通信两大类1.1 串行通信 少量数据信号线&#xff08;8根以下&#xff09;&#xff0c;数据分成一位一位的逐个依次传输 1.2 并行通信 多根数据信号线&#xff08;8根以上&#xff09;&#xff0c…

【Kubernetes知识点问答题】健康检查

目录 1. Kubernetes 对集群 Pod 和容器健康状态如何进行监控和检测的。 2. 解释 LivenessProbes 探针的作用及其适用场景。 3. 解释 ReadinessProbe 探针的作用及其适用场景。 4. 解释 StartupProbe 探针的作用及其适用场景。 5. 说明 K8s 中 Pod 级别的 Graceful Shutdown…

Rust 赋能前端:PDF 分页/关键词标注/转图片/抽取文本/抽取图片/翻转...

❝ 我从不幻想成功。我只会为了成功努力实践 大家好&#xff0c;我是柒八九。一个专注于前端开发技术/Rust及AI应用知识分享的Coder ❝ 此篇文章所涉及到的技术有 WebAssembly Mupdf Pdf操作( 分页展示/文本抽离/文本标注/获取超链接/Pdf转图片/翻转/截取) 因为&#xff0c;行文…

Redis实战宝典:开发规范与最佳实践

目录标题 Key命名设计&#xff1a;可读性、可管理性、简介性Value设计&#xff1a;拒绝大key控制Key的生命周期&#xff1a;设定过期时间时间复杂度为O(n)的命令需要注意N的数量禁用命令&#xff1a;KEYS、FLUSHDB、FLUSHALL等不推荐使用事务删除大key设置合理的内存淘汰策略使…

2024国赛数学建模A题思路模型代码

2024国赛数学建模思路资料&#xff0c;思路获取见文末名片 数学建模感想 纪念逝去的大学数学建模&#xff1a;两次校赛&#xff0c;两次国赛&#xff0c;两次美赛&#xff0c;一次电工杯。从大一下学期组队到现在&#xff0c;大三下学期&#xff0c;时间飞逝&#xff0c;我的…

深入理解红黑树:在C++中实现插入、删除和查找操作

深入理解红黑树&#xff1a;在C中实现插入、删除和查找操作 红黑树是一种自平衡二叉搜索树&#xff0c;广泛应用于各种算法和系统中。它通过颜色属性和旋转操作来保持树的平衡&#xff0c;从而保证插入、删除和查找操作的时间复杂度为O(log n)。本文将详细介绍如何在C中实现一…

学生管理系统升级(登录注册 + 关联学生管理系统)

新增需求 这是在昨天的基础初代版本上面新增一个登录注册忘记密码的功能 需求分析 注册 登录 忘记密码 user类代码呈现 package StudentSystem;public class User {private String username;private String password;private String personID;private String phoneNumber;pu…

微信小程序知识点(二)

1.下拉刷新事件 如果页面需要下拉刷新功能&#xff0c;则在页面对应的json配置文件中&#xff0c;将enablePullDownRefresh配置设置为true&#xff0c;如下 {"usingComponents": {},"enablePullDownRefresh": true } 2.上拉触底事件 在很多时候&#x…

【摸鱼笔记】python 提取和采集 finereport 未绑定目录的报表模板

背景 在企业应用过程中&#xff0c;报表一般会按照数据分析的主题、项目将多个报表放在一处&#xff0c;一些图表类报表会有通过超链接等方式&#xff0c;跳转到对应的明细报表中。 并且在正式的使用中&#xff0c;这些报表不会绑定到目录。 在梳理数据分析项目使用情况时这…

ubuntu22.04搭建elasticsearch+kibana环境

下载镜像ElasticSearch 命令&#xff1a;docker pull elasticsearch:7.6.2 部署ElasticSearch 命令&#xff1a; docker run -d --name hc-es -p 9200:9200 -p 9300:9300 -v "/home/hc/es/data":/usr/share/elasticsearch/data -e "discovery.typesingle-n…

PostgreSQL 报错 because it does not have a replica identity and publishes updates

(update,delete触发,insert不触发)because it does not have a replica identity and publishes updates Hint: To enable updating from the table, set REPLICA IDENTITY using ALTER TABLE 如果相关表涉及了逻辑复制&#xff0c;且对应表没有主键&#xff0c;则需要SET RE…

matlab中的插值与拟合(代码)

目录 1.对均匀数据的插值与拟合 2.对散点数据的拟合&#xff08;如ANSYS fluent导出的节点数据&#xff09; 1.对均匀数据的插值与拟合 interp1&#xff1a;一维插值。这是最常用的插值函数之一&#xff0c;用于对一维数据进行插值。它可以执行线性插值、最近邻插值、样条插…

青少年蓝桥杯国赛要点

1.字典的常见方法 dict——{key&#xff1a;value&#xff0c;} Python3 字典 删除操作&#xff1a; 删除键&#xff1a;del dicto[key] 删除键对应的值&#xff1a;dicto.pop(key) (2022.05出现在选择题第三题) 清空字典&#xff1a;dicto.clear() 删除字典&#xff1a;del…

kafka单机安装

kafka单机安装 下载地址 官网&#xff1a;https://kafka.apache.org/最新版本下载页面&#xff1a;https://kafka.apache.org/downloads 说明 版本选择&#xff1a;3.0.0&#xff0c;kafka_2.12-3.0.0.tgz下载地址&#xff1a;https://archive.apache.org/dist/kafka/3.0.0…

算法练习题14——leetcode84柱形图中最大的矩形(单调栈)

题目描述&#xff1a; 解题思路&#xff1a; 要解决这个问题&#xff0c;我们需要找到每个柱子可以扩展的最大左右边界&#xff0c;然后计算以每个柱子为高度的最大矩形面积。 具体步骤如下&#xff1a; 计算每个柱子左侧最近的比当前柱子矮的位置&#xff1a; 使用一个单调…

使用自制COCO数据集进行PaddleDetection模型训练

本次模型训练基于百度飞浆的Baseline&#xff1a; 19届智能车百度创意组识别 - 飞桨AI Studio星河社区 (baidu.com) 一、收集数据及数据处理 用摄像头拍摄实物&#xff0c;这里先选用baseline中给好的数据集。创建VOC文件夹&#xff0c;文件夹里包含Annotations和JPEGImages两…

双信封程序

一、双信封程序 世界银行采购的一阶段和多阶段市场方式选项&#xff0c;在实施中还涉及单信封、双信封程序。单信封是在一个信封内同时递交技术和财务投标书/建议书&#xff0c;信封打开后同时评审。双信封是第一个信封包装资格和技术部分&#xff0c;第二个信封包装财务&#…