Re解析(正则表达式解析)

正则表达式基础

元字符

B站教学视频: 正则表达式元字符基本使用

量词

贪婪匹配和惰性匹配

惰性匹配如下两张图,而 .* 就表示贪婪匹配,即尽可能多的匹配到符合的字符串,如果使用贪婪匹配,那么结果就是图中的情况三

python中re模块

re模块的常用方法

import re

# findall(正则表达式, 待匹配的字符串) -> 符合正则表达式的内容(以列表的形式返回)
# 含义:匹配字符串中所有符合正则表达式的内容(以列表的形式返回)
res_findall = re.findall(r"\d+", "中国移动:10086,中国联通:10010")
print(res_findall)  # ['10086', '10010']

# re.finditer(正则表达式, 待匹配的字符串) -> 符合正则表达式的内容(以迭代器的形式返回)
# 含义:匹配字符串中所有符合正则表达式的内容(以迭代器的形式返回)
res_finditer = re.finditer(r"\d+", "中国移动:10086,中国联通:10010")
print(res_finditer)  # <callable_iterator object at 0x000001CB2875B340>
for item in res_finditer:
    """
    下面两行输出语句的输出结果如下:
    <re.Match object; span=(5, 10), match='10086'>
    10086
    <re.Match object; span=(16, 21), match='10010'>
    10010
    
    item 中还有其他的方法,如item.start()/item.end()分别表示
    匹配到的字符串在原字符串中的起始索引和结束索引
    """
    print(item)  # 得到match对象
    print(item.group())  # 得到匹配的字符串

# re.search(正则表达式, 待匹配的字符串) -> 符合正则表达式的内容(返回match对象)
# 含义:匹配字符串中第一个匹配到的符合正则表达式的内容(返回match对象)
res_search = re.search(r"\d+", "中国移动:10086,中国联通:10010")
print(res_search)  # <re.Match object; span=(5, 10), match='10086'>
print(res_search.group())  # 10086

# 上述三种方法都是全文匹配,而match是从头开始匹配
# re.match(正则表达式, 待匹配的字符串) -> 符合正则表达式的第一个字符串内容(返回match对象)
# 含义:从待匹配的字符串的第一个字符开始匹配,将匹配到的第一个结果返回,返回的是match对象
res_match = re.match(r"\d+", "中国移动:10086,中国联通:10010")
print(res_match)  # None,字符串开头不是数字,所以等于匹配不成功,结果为空
# print(res_match.group())  # 报错
res_match = re.match(r"\d+", "10086,中国联通:10010")
print(res_match)  # <re.Match object; span=(0, 5), match='10086'>
print(res_match.group())  # 10086

# 预加载
# 应用场景:在爬虫中,想要从网页中匹配到想要的内容,匹配的正则表达式可能会很复杂,
# 而又多次的使用到该正则表达式,则可以预加载正则表达式
# 如下,好处就是该正则可以反复使用
obj = re.compile(r"\d+")
res1 = obj.findall("中国移动:10086,中国联通:10010")
res2 = obj.finditer("中国移动:10086,中国联通:10010")
res3 = obj.search("中国移动:10086,中国联通:10010")
res4 = obj.match("中国移动:10086,中国联通:10010")

分组匹配

s = """
    <div class="jay">周杰伦</div>
    <div class="jj">林俊杰</div>
"""
# (?P<name>.*?) 分组匹配(P为大写),相当于把括号中的.*?匹配到的内容给变量name
# 然后通过item.group('name')获取到name的值
# 只要把想要单独获取的内容按以上形式:(?P<xxx>正则表达式) 即可获取
# re.S 的作用就是让 . 也可以匹配到换行符
# flags 是re模块中compile、match、findall等方法的一个参数,具体用法可以百度
obj = re.compile(r'<div class=".*?">(?P<name>.*?)</div>', re.S)
res = obj.finditer(s)
print(res)  # <callable_iterator object at 0x0000020F2E89AEC0>
for item in res:
    """
    输出结果如下:
    <re.Match object; span=(5, 31), match='<div class="jay">周杰伦</div>'>
    <div class="jay">周杰伦</div>
    周杰伦
    <re.Match object; span=(36, 61), match='<div class="jj">林俊杰</div>'>
    <div class="jj">林俊杰</div>
    林俊杰
    """
    print(item)  # <re.Match object; span=(5, 31), match='<div class="jay">周杰伦</div>'>
    print(item.group())  # <div class="jay">周杰伦</div>
    print(item.group('name'))  # 周杰伦

注:关于re模块方法中的flags参数作用,可以百度一下

案例——豆瓣top250(re解析版)

B站视频教程:爬取豆瓣top250电影

import requests
import re
import csv

url = "https://movie.douban.com/top250"
headers = {
    "User-Agent": "xxx(写上自己电脑的)"
}
resp = requests.get(url, headers=headers)
# print(resp.text)  # 没加headers之前结果为空,说明网站有一些反扒机制
pattern = (r'<li>.*?<div class="item">.*?<span class="title">(?P<name>.*?)</span>.*?'
           r'导演: (?P<director>.*?)&nbsp;.*?主演: (?P<performer>.*?)...<br>.*?'
           r'<span class="rating_num" property="v:average">(?P<score>\d.\d)</span>')

obj = re.compile(pattern, re.S)
res = obj.finditer(resp.text)
# 把获取到的数据存入CSV文件,方便以后对数据进行操作
# 关于CSV文件,请百度
f = open('data.csv', mode='w', encoding='utf-8')
csv_writer = csv.writer(f)  # 表示向文件写入数据
for i in res:
    # print(i.group('name'))
    # print(i.group('director'))
    # print(i.group('performer'))
    # print(i.group('score').strip())
    dic = i.groupdict()  # 将数据以字典形式返回
    # print(dic)
    # 将字典的值按行写入文件,文件中的每一行就是一部电影的信息
    # csv文件中,每一行数据以逗号分隔每个值
    csv_writer.writerow(dic.values())
f.close()
resp.close()
print("数据解析完成!")

部分csv文件内容如下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值