② 数据解析
本文即将看到:
⚬ ------ lxml库
⚬ ------ BeautifulSoup库
⚬ ------ re正则
对比
解析工具 | 解析速度 | 使用难度 |
---|---|---|
re 正则 | 最快 | 难 |
lxml | 快 | 中 |
BeautifulSoup | 最慢 | 易 |
一、lxml库
XPath插件推荐
chrome: XPath Helper
Firefox: XPath Checker
XPath语法
1.选取节点:
表达式 | 描述 |
---|---|
nodename(节点名字) | 选取此节点的所有节点 |
/ | 绝对路径:若在最前,则从根节点开始选取 |
// | 相对路径:从全局节点中选择节点 |
@ | 选取某个节点的属性 |
谓语
用来查找某个特定节点或者包含某个指定的值的节点,被嵌在方括号中
路径表达式 | 描述 |
---|---|
/bookstore/book[1] | 选取bookstore下的第一个子元素 |
/bookstore/book[last()] | 选取bookstore下的倒数第二个book元素 |
bookstore/book[position() < 3] | 选取bookstore下前面两个子元素 |
//book[@price] | 选取拥有price属性的book元素 |
//book[@price=10] | 选取所有拥有price属性等于10的book元素 |
通配符
通配符 | 描述 |
---|---|
* | 匹配任意节点 |
@* | 匹配节点中的任何属性 |
2.选取多个属性:
/tr/td[@class=''][@id=''] 或者 /tr/td[@class=''and@id='']
3.常用函数
函数 | 功能 |
---|---|
contains(string1, string2) | 如果前后匹配则返回True, 否则False |
text() | 获取元素的文本内容 |
starts_with() | 从起始位置匹配字符串 |
4.etree模块
lxml.etree
导入
from lxml import etree
标识符 = etree.HTML(目标)
print(etree.tostring(标识符,encoding("utf-8")).decode("utf-8")
etree.parse
从文件解析html
from lxml import etree
标识符 = etree.parse(文件地址)
XPath和lxml结合示例
二、BeautifulSoup库
安装
pip install BeautifulSoup4
1.基本使用
from bs4 import BeautifulSoup
soup = BeautifulSoup(' ', '解析器') //解析器: lxml,xml,html5lib
示例
可以调用prettify()方法格式化输出HTML
//网站
soup = BeautifulSoup(resp.read(),'解析器')
//本地
soup = BeautifulSoup(open(文件名),'解析器')
2.四大对象
对象 |
---|
Tag(标签) |
NavigableString(内部文字) |
BeautifulSoup(文档的全部内容) |
Comment(特殊的NavigableString) |
<1> Tag常用属性
tag.name: 获取标签
tag.attrs: 获取标签内的所有属性,返回字典. 可用键取值,也可用get('..')获取属性
<2> NavigableString
如果想获取标签内的文字, 直接调用 .string()
<3> BeautifulSoup
可以把它当作一个Tag对象, 只是可以分别获取它的类型、名称, 具有一级属性
<4> Comment
这种对象调用.string,可以获取注释里的内容
3.BeautifulSoup的各种节点
当目标节点不好定位时,可以寻找目标附近的节点,顺藤摸瓜找到目标.
节点 | 方法 | 描述 |
---|---|---|
子节点与子孙节点 | contents | 把标签下的所有子标签存入列表,返回列表 |
children | 和contents一样,但返回的是一个迭代器 | |
父节点与祖先节点 | parent | 返回父节点Tag |
parents | 返回祖先节点,返回一个生成器对象 | |
兄弟节点 | next_sibling | 下一个兄弟节点 |
previous_element | 上一个兄弟节点 | |
前后节点 | next_element | 下一个节点 |
previous_element | 上一个节点 |
4.文档树搜索
find_all(常用)
find_all(self,name=None, attrs={}, recursive=True, text=None, limit=None, kwargs)
name: 通过HTML标签名直接搜索, 自动忽略字符串对象. 参数可以是字符串 re 列表 True 和 自定义方法
keyword: 通过HTML标签的id, href(a标签), 和title(class 要写成 class_),可以同时过滤多个,对于不能用的tag属性,可以用一个attrs字典
text: 搜索文档中的字符串内容
limit: 限制返回结果数量
recursive: 是否递归检索所有子孙节点
其他方法
方法 | 描述 |
---|---|
find | 和find_all一样,但返回的是结果 |
5.css选择器
调用select()方法传入字符串参数,即可使用css选择器语法来找到对应的tag
<1> 通过标签名查找
soup.select('a')
<2> 通过类名查找
soup.select('.brother') //类名前加个点.
<3> 通过id查找
soup.select('#link') //类名前加个点#
6.方法对比
方法 | 描述 |
---|---|
string | 获取某个标签下的非标签字符串,返回的是字符串 |
strings | 获取某个标签下的子孙非标签字符串,返回的是生成器 |
stripped_strings | 和strings相同,但会去除空白字符 |
get_text | 获取某个标签下的子孙非标签字符串,返回普通字符串 |
三、re 正则模块
使用
import re
1.规则
字符
字符 | 作用 |
---|---|
. | 匹配任意一个字符 |
[] | 匹配[]中列举的字符 |
[^...] | 匹配不在[]列举的字符 |
\d 或 \D | 匹配数字,0-9 或 匹配非数字 |
\s 或 \S | 匹配空白或非空白 |
\w | 匹配字母,数字,下划线字符: 0-9, a-Z, _ |
\W | 匹配非字母, 数字, 下划线 |
- | 匹配范围: 如[a-d] |
数量
字符 | 作用 |
---|---|
* | 前面的字符匹配任意多个字符 |
+ | 前面的字符串出现至少一次 |
? | 匹配至多出现一次的字符 |
字符出现至少m次 | |
出现m到n次 |
边界
字符 | 作用 |
---|---|
^ | 字符串开头 |
$ | 字符串结尾 |
\b | 单词边界 |
\B | 非单词边界 |
\A | 匹配字符串的开始位置 |
\Z | 匹配字符串的结束位置 |
分组
字符 | 作用 |
---|---|
| | 匹配左右任意一个表达式 |
(re) | 匹配括号内的表达式,也标识一个组 |
re模块
1.匹配
re.match( , ) //从第一个字符开始
re.search( ,) //在整个字符串中查找
2.检索与替换
re.findall(,) // 遍历字符串 返回列表
re.finditer(,) //
re.sub(目标字符串, 替换字符串,次数,flags) //替换
re.split(分割符号,) //返回列表
3.compile函数
对于一些经常用到的正则表达式,可以使用compile惊醒编译, 后期再使用的时候可以直接拿来用,提高执行效率.
compile还可以指定flag=re.VERBOSE
text = 'the number is 200.00'
r = re.compile(r"""
\d+ //小数点前面的数字
\.? //小数点
\d* //小数点后面的数字
""", re.VERBOSE)
res = re.search(r.text)
print(res.group())
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?