python3爬虫之正则表达式的使用

编程入门 行业动态 更新时间:2024-10-12 20:23:24

python3<a href=https://www.elefans.com/category/jswz/34/1770264.html style=爬虫之正则表达式的使用"/>

python3爬虫之正则表达式的使用

1.正则表达式
在抓取到网页信息后,使用正则表达式提取网页中的信息,正则表达式是处理字符串的有力工具,可以对字符串进行查找,替换,过滤操作。是事先对定义好的“规则字符串”,使用这个规则字符串来对目标文本进行过滤,非Python独有,很多语言都支持正则这种规则,python中,是re模块实现的。

2.正则表达式的测试在线站点


3.正则表达式使用的场景:
在文本数据中对数据进行筛选,清洗操作,比如在nigx服务器的日志中,使用正则来提取数据。对抓取的html中的数据进行筛选等。

4.正则表达式常见的匹配模式

模式描述
\w匹配字母数字下划线
\W匹配非字母数字下划线
\s匹配任意空白字符,等价于[\t\n\r\f]
\S匹配任意非空字符
\d匹配任意数字
\D匹配任意非数字
\A匹配字符串开始
\Z匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串
\z匹配字符串结束
\G匹配最后匹配完成的位置
\n匹配一个换行符
\t匹配一个制表符
^匹配字符串开头
$匹配字符串末尾
.匹配任意字符,除了换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符
[…]用来表示一组字符,单独列出:[amk]匹配’a’,‘m’或’k’
[^…]不在[]中的字符:[^abc]匹配除了a,b,c之外的字符
*匹配0个或多个的表达式
+匹配一个或多个表达式
?匹配0个或1个由前面的正则表达式定义的片段,非贪婪方式
{n}精确匹配n个前面表达式
{n,m}匹配n到m次由前面的正则表达式定义的片段,非贪婪方式
ab
()匹配括号内的表达式,也表示一个组

5.python中正则表达式的使用
re.match 此方法尝试从字符串开始位置匹配一个模式,如果第一个字符不匹配的话,match()就返回none,不在继续匹配
re.match(pattern,string,flags=0)

6.最常规的匹配

# 导入库
import re
# 定义字符串
content = 'Hello 123 4567 World_This is a Regex Demo'
print(len(content))
result = re.match('^Hello\s\d\d\d\s\d{4}\s\w{10}.*Demo$',content)
# 输出匹配描述对象
print(result)
# 输出匹配的内容
print(result.group())
# 输出匹配的子串的下标范围
print(result.span())
41
<_sre.SRE_Match object; span=(0, 41), match='Hello 123 4567 World_This is a Regex Demo'>
Hello 123 4567 World_This is a Regex Demo
(0, 41)

7.泛匹配

import re
content = 'Hello 123 4567 World_This is a Regex Demo'
# 匹配相同的字符串,上面的正则表达式很长,使用起来不方便,不够通用,
# 使用.*把表达式进行改进,也能达到相同的结果
result = re.match('^Hello.*Demo$',content)
# 输出匹配描述对象
print(result)
# 输出匹配的内容
print(result.group())
# 输出匹配的子串的下标范围
print(result.span())
<_sre.SRE_Match object; span=(0, 41), match='Hello 123 4567 World_This is a Regex Demo'>
Hello 123 4567 World_This is a Regex Demo
(0, 41)

8.匹配字符串中的目标,提取目标字符串

import recontent = 'Hello 1234567 World_This is a Regex Demo'
# 从字符串中提供数字,正则表达式中的()部分
result = re.match('^Hello\s(\d+)\sWorld.*Demo$',content)
print(result)
# 默认输出正则表达式匹配的所有字符串
print(result.group())
# group(1)表示正则中匹配第一个小括号的字符串内容
print(result.group(1))
print(result.span())
<_sre.SRE_Match object; span=(0, 40), match='Hello 1234567 World_This is a Regex Demo'>
Hello 1234567 World_This is a Regex Demo
1234567
(0, 40)

9.贪婪匹配

import re
content = 'Hello 1234567 World_This is a Regex Demo'
# *号后面没有?号,是贪婪模式,会匹配更多的字符串,吃掉后面的数字,使得()中只匹配一个数字7
result = re.match('^He.*(\d+).*Demo$',content)
print(result)
print(result.group(1))
<_sre.SRE_Match object; span=(0, 40), match='Hello 1234567 World_This is a Regex Demo'>
7

10.非贪婪匹配

import re
content = 'Hello 1234567 World_This is a Regex Demo'
# *号后面加上?号,后面的()中是数字,那么数字就作为一个整体,?号前面的*尽可能匹配
# 较少的字符,这就称为非贪婪模式
result = re.match('^He.*?(\d+).*Demo$',content)
print(result)
print(result.group(1))
<_sre.SRE_Match object; span=(0, 40), match='Hello 1234567 World_This is a Regex Demo'>
1234567
  1. 匹配模式
import re
# 字符串中出现了换行符
content = '''Hello 1234567 World_This 
is a Regex Demo'''
# 使用参数 re.S使得 .*可以匹配任意多个字符,包括换行符,否则遇到换行符终止
result = re.match('^He.*?(\d+).*?Demo$',content, re.S)
print(result)
print(result.group(1))
<_sre.SRE_Match object; span=(0, 41), match='Hello 1234567 World_This \nis a Regex Demo'>
1234567
  1. 转义
import recontent = 'price is $5.00'
# 对于目标字符串中有特殊字符的,$符, .符号等,在正则中要使用转义(因为这些符号在
# 正则表达式中已经有其他的含义),使之具有原来的含义就要用转义符,否则无法匹配
# result = re.match('price is $5.00',content)
result = re.match('price is \$5\.00',content)
print(result)
<_sre.SRE_Match object; span=(0, 14), match='price is $5.00'>

总结:尽量使用泛匹配,使用括号的到匹配目标,尽量使用非贪婪模式,有换行符就用re.S

13. re.search
re.search扫描整个字符串并返回第一个成功的匹配
下面使用search方法和match方法做比较
# match方法
import re
content = 'Extra strings Hello 1234567 World_This is a Regex Demo Extra strings'
# match方法严格从目标字符串的第一个字符开始匹配,如果第一个字符不匹配,返回None并结束
result = re.match('Hello.*?(\d+).*?Demo',content)
print(result)
None
# search方法
import re
content = 'Extra strings Hello 1234567 World_This is a Regex Demo Extra strings'
# serch方法从目标字符串中搜索正则中的子串,返回匹配的第一个结果
result = re.search('Hello.*?(\d+).*?Demo',content)
print(result)
<_sre.SRE_Match object; span=(14, 54), match='Hello 1234567 World_This is a Regex Demo'>
总结:为了匹配方便,能使用search就不用match

14.匹配演练

import rehtml = '''<div id="songs-list"><h2 class="title">经典老歌</h2><p class="introduction">经典老歌列表</p><ul id="list" class="list-group"><li data-view="2">一路上有你</li><li data-view="7"><a href="/2.mp3" singer="任贤齐">沧海一声笑</a></li><li data-view="4" class="active"><a href="/3.mp3" singer="齐秦">往事随风</a></li><li data-view="6"><a href="/4.mp3" singer="beyond">光辉岁月</a></li><li data-view="5"><a href="/5.mp3" singer="陈慧琳">记事本</a></li><li data-view="5"><a href="/6.mp3" singer="邓丽君"><i class="fa fa-user"></i>但愿人长久</a></li></ul>
</div>'''# 目标,提取齐秦的名字和歌曲
result = re.search('<li.*?active.*?singer="(.*?)">(.*?)</a>',html,re.S)
if result:print(result.group(1),result.group(2))
齐秦 往事随风
import rehtml = '''<div id="songs-list"><h2 class="title">经典老歌</h2><p class="introduction">经典老歌列表</p><ul id="list" class="list-group"><li data-view="2">一路上有你</li><li data-view="7"><a href="/2.mp3" singer="任贤齐">沧海一声笑</a></li><li data-view="4" class="active"><a href="/3.mp3" singer="齐秦">往事随风</a></li><li data-view="6"><a href="/4.mp3" singer="beyond">光辉岁月</a></li><li data-view="5"><a href="/5.mp3" singer="陈慧琳">记事本</a></li><li data-view="5"><a href="/6.mp3" singer="邓丽君"><i class="fa fa-user"></i>但愿人长久</a></li></ul>
</div>'''# 目标,提取任贤齐的名字和歌曲
result = re.search('<li.*?singer="(.*?)">(.*?)</a>',html,re.S)
if result:print(result.group(1),result.group(2))
任贤齐 沧海一声笑
import rehtml = '''<div id="songs-list"><h2 class="title">经典老歌</h2><p class="introduction">经典老歌列表</p><ul id="list" class="list-group"><li data-view="2">一路上有你</li><li data-view="7"><a href="/2.mp3" singer="任贤齐">沧海一声笑</a></li><li data-view="4" class="active"><a href="/3.mp3" singer="齐秦">往事随风</a></li><li data-view="6"><a href="/4.mp3" singer="beyond">光辉岁月</a></li><li data-view="5"><a href="/5.mp3" singer="陈慧琳">记事本</a></li><li data-view="5"><a href="/6.mp3" singer="邓丽君">但愿人长久</a></li></ul>
</div>'''# 去掉re.S,那么匹配时正则中就无法匹配到有换行的字符串,就是说正则中的.不能代替换行符进行
# 匹配
result = re.search('<li.*?singer="(.*?)">(.*?)</a>',html)
if result:print(result.group(1),result.group(2))
beyond 光辉岁月

15.re.findall方法
搜索字符串时,以列表形式返回全部能匹配的子串

import rehtml = '''<div id="songs-list"><h2 class="title">经典老歌</h2><p class="introduction">经典老歌列表</p><ul id="list" class="list-group"><li data-view="2">一路上有你</li><li data-view="7"><a href="/2.mp3" singer="任贤齐">沧海一声笑</a></li><li data-view="4" class="active"><a href="/3.mp3" singer="齐秦">往事随风</a></li><li data-view="6"><a href="/4.mp3" singer="beyond">光辉岁月</a></li><li data-view="5"><a href="/5.mp3" singer="陈慧琳">记事本</a></li><li data-view="5"><a href="/6.mp3" singer="邓丽君">但愿人长久</a></li></ul>
</div>'''# 查找所有的li标签中的带有href的连接,人名,作品
result = re.findall('<li.*?href="(.*?)".*?singer="(.*?)">(.*?)</a>',html,re.S) 
# 结果以列表返回,里边中包含匹配的多个子串的元组
print(result)
print(type(result))
# 遍历列表中的元素
for r in result:print(r)
[('/2.mp3', '任贤齐', '沧海一声笑'), ('/3.mp3', '齐秦', '往事随风'), ('/4.mp3', 'beyond', '光辉岁月'), ('/5.mp3', '陈慧琳', '记事本'), ('/6.mp3', '邓丽君', '但愿人长久')]
<class 'list'>
('/2.mp3', '任贤齐', '沧海一声笑')
('/3.mp3', '齐秦', '往事随风')
('/4.mp3', 'beyond', '光辉岁月')
('/5.mp3', '陈慧琳', '记事本')
('/6.mp3', '邓丽君', '但愿人长久')
import rehtml = '''<div id="songs-list"><h2 class="title">经典老歌</h2><p class="introduction">经典老歌列表</p><ul id="list" class="list-group"><li data-view="2">一路上有你</li><li data-view="7"><a href="/2.mp3" singer="任贤齐">沧海一声笑</a></li><li data-view="4" class="active"><a href="/3.mp3" singer="齐秦">往事随风</a></li><li data-view="6"><a href="/4.mp3" singer="beyond">光辉岁月</a></li><li data-view="5"><a href="/5.mp3" singer="陈慧琳">记事本</a></li><li data-view="5"><a href="/6.mp3" singer="邓丽君">但愿人长久</a></li></ul>
</div>'''
# 上面例子的正则没有匹配到第一个li标签中的歌名,因为第一个标签中的歌名没有href标签
# 为了匹配第一个歌名,正则如下
# 考虑到众多的li标签中有换行,所以使用re.S去掉换行
# 小括号括起来的正则可以作为一个整体,后面使用?号代表前面的正则表达式在字符串串中可以有,
# 可以没有
result = re.findall('<li.*?>\s*?(<a.*?)?(\w+)(</a>)?\s*?</li>',html,re.S)
print(result)
# 遍历列表中元组的第一个元素
for r in result:print(r[1])
[('', '一路上有你', ''), ('<a href="/2.mp3" singer="任贤齐">', '沧海一声笑', '</a>'), ('<a href="/3.mp3" singer="齐秦">', '往事随风', '</a>'), ('<a href="/4.mp3" singer="beyond">', '光辉岁月', '</a>'), ('<a href="/5.mp3" singer="陈慧琳">', '记事本', '</a>'), ('<a href="/6.mp3" singer="邓丽君">', '但愿人长久', '</a>')]
一路上有你
沧海一声笑
往事随风
光辉岁月
记事本
但愿人长久
  1. re.sub方法
    将匹配到的子串用指定的字符串替换,然后返回替换后的字符串
import recontent = 'Extra strings Hello 1234567 World_This is a Regex Demo Extra strings'
# 查找数字并替换为空
content = re.sub('\d+','',content)
print(content)
Extra strings Hello  World_This is a Regex Demo Extra strings
import re
content = 'Extra strings Hello 1234567 World_This is a Regex Demo Extra strings'
# 查找数字并替换为空
content = re.sub('\d+','Replacement',content)
print(content)
Extra strings Hello Replacement World_This is a Regex Demo Extra strings
import recontent = 'Extra strings Hello 1234567 World_This is a Regex Demo Extra strings'
# 查找数字并替换为空,要替换的内容包含前面的查找到的引用
# 使用r' 反斜杠1 表示要替换的内容引用到了第一个括号,即查找到的内容
content = re.sub('(\d+)',r'\1 8910',content)
print(content)
Extra strings Hello 1234567 8910 World_This is a Regex Demo Extra strings
# 使用sub和findall两个方法结合,获取html文档中的歌名
import rehtml = '''<div id="songs-list"><h2 class="title">经典老歌</h2><p class="introduction">经典老歌列表</p><ul id="list" class="list-group"><li data-view="2">一路上有你</li><li data-view="7"><a href="/2.mp3" singer="任贤齐">沧海一声笑</a></li><li data-view="4" class="active"><a href="/3.mp3" singer="齐秦">往事随风</a></li><li data-view="6"><a href="/4.mp3" singer="beyond">光辉岁月</a></li><li data-view="5"><a href="/5.mp3" singer="陈慧琳">记事本</a></li><li data-view="5"><a href="/6.mp3" singer="邓丽君">但愿人长久</a></li></ul>
</div>'''
# 使用sub方法去掉<a></a>标签字符,也就是使用sub把目标字符串替换成空字符串
html = re.sub('<a.*?>|</a>','',html)
# 然后再使用findall提取li标签中的歌名,就会方便很多
result = re.findall('<li.*?>(.*?)</li>',html,re.S)
print(result)
for r in result:# 找出所有匹配的结果,并使用strip去掉换行打印出每一个print(r.strip())
['一路上有你', '\n            沧海一声笑\n        ', '\n            往事随风\n        ', '光辉岁月', '记事本', '\n            但愿人长久\n        ']
一路上有你
沧海一声笑
往事随风
光辉岁月
记事本
但愿人长久

17.repile
此方法可以将正则表达式编译为正则对象,以便于以后复用这个正则对象来进行模式匹配

import recontent = '''Hello 1234567 World_This
is a Regex Demo'''
# 将正则表达式编译为正则对象
pattern = repile("Hello.*Demo",re.S)
# 复用这个正则对象
result = re.match(pattern,content)
# result = re.match("Hello.*Demo",content,re.S)
print(result)
<_sre.SRE_Match object; span=(0, 40), match='Hello 1234567 World_This\nis a Regex Demo'>

18.实战练习

import requests
import re
content = requests.get('/').text
# 提取豆瓣主页中对应的书的链接,书名,作者,出版时间,使用re.S使得.号匹配换行
pattern = repile('<li.*?cover.*?href="(.*?)".*?title="(.*?)".*?more-meta.*?author">(.*?)</span>.*?year">(.*?)</span>.*?</li>',re.S)
# 按正则表达式搜索整个html文档
results = re.findall(pattern,content)
print(results)
for result in results:# 将列表中的每个元组给赋值url,name,author,date = result# 去掉author,date中的换行符author = re.sub('\s',"",author)date = re.sub('\s',"",date)# 打印每个元组print(url,name,author,date)

更多推荐

python3爬虫之正则表达式的使用

本文发布于:2024-02-10 18:43:49,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1676742.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:爬虫   正则表达式

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!