🔥一个人走得远了,就会忘记自己为了什么而出发,希望你可以不忘初心,不要随波逐流,一直走下去🎶
🦋 欢迎关注🖱点赞👍收藏🌟留言🐾
🦄 本文由 程序喵正在路上 原创,CSDN首发!
💖 系列专栏:Python爬虫
🌠 首发时间:2022年8月9日
✅ 如果觉得博主的文章还不错的话,希望小伙伴们三连支持一下哦
数据解析概述
前面,我们基本上掌握了抓取整个网页的基本技能,但是,在大多数情况下,我们并不需要整个网页的内容,只是需要那么一小部分,怎么办呢?
接下来,我们将会学习三种解析方式:
- re解析
- bs4解析
- xpath解析
这三种方式可以混合进行使用,完全以结果为导向,只要能拿到你想要的数据,用什么方案并不重要,当你掌握了这些之后,再考虑性能的问题
正则表达式
正则表达式(Regular Expression),是一种使用表达式的方式对字符串进行匹配的语法规则
其实我们抓取到的网页源代码,本质上就是一个超长的字符串,想从里面提取内容,用正则再合适不过了
正则表达式的优点:速度快,效率高,准确性高;正则表达式的缺点:新手上手难度有一点点高
不过只要掌握了正则编写的逻辑关系,写出一个提取页面内容的正则其实并不复杂
正则的语法:使用元字符进行排列组合用来匹配字符串
推荐一个在线正则表达式测试网站
元字符:具有固定含义的特殊符号
常用元字符有:
元字符 | 描述 |
---|---|
. | 匹配除换行符以外的任意字符 |
\w | 匹配字母或数字或下划线 |
\s | 匹配任意的空白符 |
\d | 匹配数字 |
\n | 匹配一个换行符 |
\t | 匹配一个制表符 |
^ | 匹配字符串的开始 |
$ | 匹配字符串的结尾 |
\W | 匹配非字母或数字或下划线 |
\D | 匹配非数字 |
\S | 匹配非空白符 |
a | b | 匹配字符a或字符b |
() | 匹配括号内的表达式,也表示一个组 |
[…] | 匹配字符组中的字符 |
[^…] | 匹配除了字符组中字符的所有字符 |
量词:控制前面的元字符出现的次数
量词 | 描述 |
---|---|
* | 重复零次或更多次 |
+ | 重复一次或更多次 |
? | 重复零次或一次 |
{n} | 重复n次 |
{n, } | 重复n次或更多次 |
{n, m} | 重复n到m次 |
贪婪匹配和惰性匹配
符号 | 对应 |
---|---|
.* | 贪婪匹配 |
.*? | 惰性匹配 |
写爬虫用的最多的就是惰性匹配
我们来看一下几个实例
所以,我们可以发现有这样⼀个规律: .*?表示尽可能少的匹配,.*表示尽可能多的匹配
re模块
学会写正则表达式后,接下来的问题是 —— 怎么在 Python 程序中去使用正则
呢?
答案是 re模块
在re模块中,我们只需要记住下面几个功能就足够使用了
1. findall
findall:匹配字符串中所有的符合正则的内容,返回类型为 list
不是很常用,因为当字符串很长的时候,用列表来处理效率是很低的
代码演示
import re
lst = re.findall(r"\d+", "我的电话号是:10086,我的电话号是:10010")
print(lst)
运行结果
2. finditer
finditer 和 findall 差不多,只不过返回类型的是迭代器,从迭代器中拿到内容需要调用 group() 函数
很常用
代码演示
it = re.finditer(r"\d+", "我的电话号是:10086,我的电话号是:10010")
for i in it:
print(i.group())
运行结果
3. search
search 会进行匹配,但是如果匹配到了第⼀个结果,就会返回这个结果的 match 对象;如果匹配不上,search 返回的则是 None
代码演示
s = re.search(r"\d+", "我的电话号是:10086,我的电话号是:10010")
print(s.group())
运行结果
4. match
match 只能从字符串的开头进行匹配,所以也不是很常用
代码演示
s = re.match(r"\d+", "我的电话号是:10086,我的电话号是:10010")
print(s.group())
运行结果
5. compile()
compile() 可以将⼀个长长的正则进行预加载,方便后面的使用,可以提高一点点效率,并且可以反复使用
代码演示
obj = re.compile(r"\d+")
ret = obj.finditer("我的电话号是:10086,我的电话号是:10010")
for it in ret:
print(it.group())
ret = obj.findall("今天是2022年8月7日")
print(ret)
运行结果
6. 提取正则中的内容
(?P<分组名称>正则),这个式子可以单独从正则匹配的内容中进一步提取内容
代码演示
import re
s = """
<div class='peppa'><span id='1'>佩奇</span></div>
<div class='george'><span id='2'>乔治</span></div>
<div class='xiongda'><span id='3'>熊大</span></div>
<div class='xionger'><span id='4'>熊二</span></div>
<div class='man'><span id='5'>光头强</span></div>
"""
# (?P<分组名称>正则),这个式子可以单独从正则匹配的内容中进一步提取内容
obj = re.compile(r"<div class='.*?'><span id='(?P<id>\d+)'>(?P<name>.*?)</span></div>", re.S) # re.S 让.能匹配换行符
result = obj.finditer(s)
for it in result:
print(it.group("id") + " " + it.group("name"))
运行结果
🧸 这次的分享就到这里啦,继续加油哦^^
🐱 我是程序喵,陪你一点点进步
🍭 有出错的地方欢迎在评论区指出来,共同进步,谢谢啦