现在
你已经会使用 python 模拟浏览器
进行一些 Http 的请求了
那么请求完之后
服务器返回给我们一堆源代码
我们可不是啥都要的啊
我们是有原则的
我们想要的东西
怎么能一股脑的啥都往自己兜里塞呢?
进群:700341555可以获取Python入门学习资料!
使不得
使不得
所以
在服务器返回给我们的源码之中
我们要过滤
拿到我们想要的就好
其它就丢一旁
那么
我们就需要学会怎么使用
正则表达式
通过它
我们才能过滤出我们想要的内容
...
接下来就是
学习 python 的正确姿势
真香警告
这篇文章不适合急性子的人看,要不然会把手机砸了的!但是,如果你能看完,那么正则表达式对你来说,算个 p 的难度啊?
其实
正则表达式不仅仅适用于 python
很多编程语言
很多地方都会使用到正则
试想一下
如何从下面这段字符串中快速检索所有的数字出来呢?
zui12shu234ai45der6en7sh88ixia7898os0huaib
简单来说
正则表达式就是定义一些特殊的符号
来匹配不同的字符
比如
d
就可以代表
一个数字,等价于 0-9 的任意一个
那么你肯定想知道
其它的特殊符号表示的啥意思吧?
恩
就不告诉你
本篇完
再见
这是各种符号的解释
你能看到这里
也是
不知道你看懵逼了没?
反正我是不想看了
接下来
才是干货
小帅b就给你精简一下
通俗的把最常用的匹配告诉你
ok
知道了这些之后
我们怎么用 python 来进行判断呢?
那就要使用到 python 的库了
它就是
re
接下来我们就来使用 re 模块
对其常用的方法
来使用正则表达式
re.match
使用这个方法
主要传入两个参数
第一个就是我们的匹配规则
第二个就是需要被过滤的内容
例如
我们想要从这
<pre class="ql-align-justify" style="-webkit-tap-highlight-color: transparent; box-sizing: border-box; font-family: Consolas, Menlo, Courier, monospace; font-size: 16px; white-space: pre-wrap; position: relative; line-height: 1.5; color: rgb(153, 153, 153); margin: 1em 0px; padding: 12px 10px; background: rgb(244, 245, 246); border: 1px solid rgb(232, 232, 232); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">Xiaoshuaib has 100 bananas
</pre>
拿到一个数字
那么我们就可以这样
<pre class="ql-align-justify" style="-webkit-tap-highlight-color: transparent; box-sizing: border-box; font-family: Consolas, Menlo, Courier, monospace; font-size: 16px; white-space: pre-wrap; position: relative; line-height: 1.5; color: rgb(153, 153, 153); margin: 1em 0px; padding: 12px 10px; background: rgb(244, 245, 246); border: 1px solid rgb(232, 232, 232); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">import re
content = 'Xiaoshuaib has 100 bananas'
res = re.match('^Xi.(d+)s.s/pre>,content)
print(res.group(1))
</pre>
通过我们刚刚说的匹配符号
可以定义出相应的匹配规则
在这里我们将我们需要的目标内容用 () 括起来
此刻我们获得结果是
0
那么如果我们想要 100 这个数字呢?
可以这样
<pre class="ql-align-justify" style="-webkit-tap-highlight-color: transparent; box-sizing: border-box; font-family: Consolas, Menlo, Courier, monospace; font-size: 16px; white-space: pre-wrap; position: relative; line-height: 1.5; color: rgb(153, 153, 153); margin: 1em 0px; padding: 12px 10px; background: rgb(244, 245, 246); border: 1px solid rgb(232, 232, 232); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">import re
content = 'Xiaoshuaib has 100 bananas'
res = re.match('^Xi.?(d+)s.s/pre>,content)
print(res.group(1))
</pre>
看出区别了么
第二段代码我们多了一个 ?符号
在这里呢
涉及到两个概念
一个是
贪婪匹配
另一个是
非贪婪匹配
所谓贪婪匹配
就是我们的第一段代码
一个数一个数都要去匹配
而非贪婪呢
我们是直接把 100 给匹配出来了
刚刚我们用到的
.?*
是我们在匹配过程中最常使用到的
表示的就是匹配任意字符
但是
.*?的 . 代表所有的单个字符,除了
如果我们的字符串有换行了
怎么办呢?
比如这样
<pre class="ql-align-justify" style="-webkit-tap-highlight-color: transparent; box-sizing: border-box; font-family: Consolas, Menlo, Courier, monospace; font-size: 16px; white-space: pre-wrap; position: relative; line-height: 1.5; color: rgb(153, 153, 153); margin: 1em 0px; padding: 12px 10px; background: rgb(244, 245, 246); border: 1px solid rgb(232, 232, 232); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">content = """Xiaoshuaib has 100
bananas"""
</pre>
那么我们就需要用到 re 的匹配模式了
说来也简单
直接用 re.S 就可以了
<pre class="ql-align-justify" style="-webkit-tap-highlight-color: transparent; box-sizing: border-box; font-family: Consolas, Menlo, Courier, monospace; font-size: 16px; white-space: pre-wrap; position: relative; line-height: 1.5; color: rgb(153, 153, 153); margin: 1em 0px; padding: 12px 10px; background: rgb(244, 245, 246); border: 1px solid rgb(232, 232, 232); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">import re
content = """Xiaoshuaib has 100
bananas"""
res = re.match('^Xi.?(d+)s.s/pre>,content,re.S)
print(res.group(1))
</pre>
可能有些朋友会觉得
匹配一个东西还要写开头结尾
有点麻烦
那么就可以使用 re 的另一个方法了
re.search
它会直接去扫描字符串
然后把匹配成功的第一个结果的返回给你
<pre class="ql-align-justify" style="-webkit-tap-highlight-color: transparent; box-sizing: border-box; font-family: Consolas, Menlo, Courier, monospace; font-size: 16px; white-space: pre-wrap; position: relative; line-height: 1.5; color: rgb(153, 153, 153); margin: 1em 0px; padding: 12px 10px; background: rgb(244, 245, 246); border: 1px solid rgb(232, 232, 232); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">import re
content = """Xiaoshuaib has 100
bananas"""
res = re.search('Xi.?(d+)s.s',content,re.S)
print(res.group(1))
</pre>
这样子也是可以获取 100 的
但是如果我们的内容是这样的
<pre class="ql-align-justify" style="-webkit-tap-highlight-color: transparent; box-sizing: border-box; font-family: Consolas, Menlo, Courier, monospace; font-size: 16px; white-space: pre-wrap; position: relative; line-height: 1.5; color: rgb(153, 153, 153); margin: 1em 0px; padding: 12px 10px; background: rgb(244, 245, 246); border: 1px solid rgb(232, 232, 232); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">content = """Xiaoshuaib has 100 bananas;
Xiaoshuaib has 100 bananas;
Xiaoshuaib has 100 bananas;
Xiaoshuaib has 100 bananas;"""
</pre>
想要获取所有的 100 呢?
这时候就要用到 re 的另一个方法了
re.findall
通过它我们就能轻松的获取所有匹配的内容了
<pre class="ql-align-justify" style="-webkit-tap-highlight-color: transparent; box-sizing: border-box; font-family: Consolas, Menlo, Courier, monospace; font-size: 16px; white-space: pre-wrap; position: relative; line-height: 1.5; color: rgb(153, 153, 153); margin: 1em 0px; padding: 12px 10px; background: rgb(244, 245, 246); border: 1px solid rgb(232, 232, 232); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">import re
content = """Xiaoshuaib has 100 bananas;
Xiaoshuaib has 100 bananas;
Xiaoshuaib has 100 bananas;
Xiaoshuaib has 100 bananas;"""
res = re.findall('Xi.?(d+)s.?s;',content,re.S)
print(res)
</pre>
这里的结果是
['100', '100', '100', '100']
又有朋友觉得
如果我们想直接替换匹配的内容呢
就比如刚刚的字符串
可不可以把 100 直接替换成 250 呢?
那就要用到 re 的另一个方法了
re.sub
可以这样
<pre class="ql-align-justify" style="-webkit-tap-highlight-color: transparent; box-sizing: border-box; font-family: Consolas, Menlo, Courier, monospace; font-size: 16px; white-space: pre-wrap; position: relative; line-height: 1.5; color: rgb(153, 153, 153); margin: 1em 0px; padding: 12px 10px; background: rgb(244, 245, 246); border: 1px solid rgb(232, 232, 232); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">import re
content = """Xiaoshuaib has 100 bananas;
Xiaoshuaib has 100 bananas;
Xiaoshuaib has 100 bananas;
Xiaoshuaib has 100 bananas;"""
content = re.sub('d+','250',content)
print(content)
</pre>
那么结果就变成了
Xiaoshuaib has 250 bananas;
Xiaoshuaib has 250 bananas;
Xiaoshuaib has 250 bananas;
Xiaoshuaib has 250 bananas;
250 个香蕉
吃....得完么??
再来说说 re 的另一个常用到的方法吧
re.compile
这个主要就是把我们的匹配符封装一下
<pre class="ql-align-justify" style="-webkit-tap-highlight-color: transparent; box-sizing: border-box; font-family: Consolas, Menlo, Courier, monospace; font-size: 16px; white-space: pre-wrap; position: relative; line-height: 1.5; color: rgb(153, 153, 153); margin: 1em 0px; padding: 12px 10px; background: rgb(244, 245, 246); border: 1px solid rgb(232, 232, 232); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">import re
content = "Xiaoshuaib has 100 bananas"
pattern = re.compile('Xi.?(d+)s.s',re.S)
res = re.match(pattern,content)
print(res.group(1))
</pre>
其实和我们之前写的一样的
<pre class="ql-align-justify" style="-webkit-tap-highlight-color: transparent; box-sizing: border-box; font-family: Consolas, Menlo, Courier, monospace; font-size: 16px; white-space: pre-wrap; position: relative; line-height: 1.5; color: rgb(153, 153, 153); margin: 1em 0px; padding: 12px 10px; background: rgb(244, 245, 246); border: 1px solid rgb(232, 232, 232); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">res = re.match('^Xi.?(d+)s.s/pre>,content,re.S)
</pre>
只不过 compile 一下
便于以后复用
好了
关于 re 模块和正则表达式就介绍完啦
知道了怎么请求数据
也知道了将返回的数据如何正则过滤
那么
爬虫对我们来说还难么?
这次本篇真的完啦
再见
网友评论