python爬虫必备-re库及正则表达式详解

re库及正则表达式详解

在前两节中我们已经了解了怎么下载html,发起请求,获取响应字符串了,那么剩下的就当然是从html中提取我们需要的数据了,在python中提取数据有几种方式,其中一种是最原始的正则表达式提取,这种方式比较麻烦,维护起来费劲,因为正则表达式不是很容易被理解,但我们还是能经常用到它,比如,在提取完大段数据后,有时候我们需要用正则来提取其中更简短的信息,总之肯定会经常用到,无论大型项目还是小的爬虫脚本。

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

从字符串开头开始匹配,一旦开头不匹配,则失败

content = 'Hello 123 4567 World_This is a Regex Demo'
print(len(content))
# 41
result = re.match('^Hello\s\d\d\d\\s\d{4}\s\w{10}', content)
print(result)
# <re.Match object; span=(0, 25), match='Hello 123 4567 World_This'>
print(result.group())
# Hello 123 4567 World_This
print(result.span())
# (0, 25)`
3. 提取目标数据

正则表达式中带圆括号的部分就是待提取的目标数据,我们可以利用 group(1) 表达式将它提取出来。
如果不引入括号,整个表达式作为一个组,是group(0),如果有括号,那么第一个括号的分组就是group(1) ,以此类推第二个括号的分组就是group(2)第二组匹配的数据。

# 匹配目标
content = 'Hello 123 4567 World_This is a Regex Demo'
result = re.match('^Hello\s(\d+)\s\d{4}\sWorld', content)
print(result.group(1))
# 123
4. 通用匹配
content = 'Hello 123 4567 World_This is a Regex Demo'
result = re.match('^Hello\s.*Demo$', content)
print(result.group())
# Hello 123 4567 World_This is a Regex Demo
print(result.span())
# (0, 41)
5. 贪婪与非贪婪
  • 贪婪模式:正则表达式一般趋向于最大长度匹配,也就是所谓的贪婪匹配。
  • 非贪婪模式:在整个表达式匹配成功的前提下,尽可能少的匹配。

在python中默认采用的是贪婪模式,使用非贪婪模式的话,只需要在量词后面直接加上一个问号”?”

# .*? 非贪婪模式
content = 'Hello 123 4567 World_This is a Regex Demo'
result = re.match('^Hello\s.*?(\d+).*Demo$', content)
print(result.group(1))
# 123
content = 'http://weibo.com/comment/kEraCN'
result1 = re.match('http.*?comment/(.*?)', content)
print('result1', result1.group(1))
# result1
result2 = re.match('http.*?comment/(.*)', content)
print('result2', result2.group(1))
# result2 kEraCN
6. 修饰符
  • re.I 匹配大小写不敏感
  • re.L 做本地化识别匹配
  • re.M 多行匹配,影响^和$
  • re.S 使.匹配包括换行在内的所有字符
  • re.U 根据Unicode字符集解析字符,这个标志影响\w \W \b \B
  • re.X 更灵活的格式
content = 'his  username is ddd999!'
result= re.search(r'ddd(\d{3})', content, re.I | re.M)
print(result.group(1))
# 999
7. 转义匹配
content = '(百度)www.baidu.com'
result = re.match('\(百度\)www\.baidu\.com', content)
print(result.group())
8. search查找首次匹配

search用来扫描整个字符串并返回第一个成功的匹配,如果匹配失败search()就返回None。

html = '''
    <li class="active">
        <a href="/3.mp3" singer="齐秦">往事随风</a>
    </li>
    <li>
        <a href="/2.mp3" singer="任贤齐">沧海一声笑</a>
    </li>
    <li>
        <a href="/1.mp3" singer="beyond">光辉岁月</a>
    </li>
    '''
result = re.search('<li.*?singer="(.*?)">(.*?)</a>', html, re.S)
if result:
    print(result.group(1), result.group(2))
# 齐秦 往事随风
9. findall 查找匹配所有

findall可以遍历匹配,可以获取字符串中所有匹配的字符串,返回一个列表

results = re.findall('<li.*?href="(.*?)".*?singer="(.*?)">(.*?)</a>', html, re.S)
print(results)
print(type(results))
for result in results:
    print(result)
    print(result[0], result[1], result[2])
    
# [('/3.mp3', '齐秦', '往事随风'), ('/2.mp3', '任贤齐', '沧海一声笑'), ('/1.mp3', 'beyond', '光辉岁月')]
11. sub替换匹配字符串

sub用来替换匹配的字符串,在解析复杂的html时,可以用sub先来删除那些没有用的字符串,常用语简化复杂的原始字符串的场景。

content = "87fsdfss87f878asda76d78090ads897a8s"
content = re.sub('\d+', '', content)
print(content)
# fsdfssfasdadadsas

# 可以用来先删除节点,再提取内容,比较简单
html = re.sub('<a.*?>|</a>', '', html)
print(html)
results = re.findall('<li.*?>(.*?)</li>', html, re.S)
for result in results:
    print(result.strip())
12. compile编译正则表达式

有时我们会先将固定不变的正则表达式编译成对象,再用这个对象来匹配不同的字符串,用以提高脚本的效率。

content1 = '2016-10-11 12:00'
content2 = '2017-12-08 12:00'
content3 = '2018-06-18 12:00'
pattern = re.compile('\d{2}:\d{2}')
result1 = re.sub(pattern, '', content1)
result2 = re.sub(pattern, '', content2)
result3 = re.sub(pattern, '', content3)
print(result1,result2,result3)
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值