爬虫入门—数据解析基础之正则表达式

爬虫入门—数据解析基础之正则表达式


Author: Labyrinthine Leo   Init_time: 2021.02.22


Key Words: Spiderre


公众号:Leo的博客城堡

爬虫入门—数据解析基础之正则表达式_第1张图片


爬虫入门—数据解析基础之正则表达式_第2张图片


爬虫网页数据解析

**前言:**前几节学习了如何使用requests模块对普通静态页面和异步加载数据页面信息进行爬取,这些都是对整个网页获取数据或者获取响应的json数据,还未涉及到开头之前降到的聚焦爬虫中的数据解析。从这一节开始进行网页数据解析的案例实战。

1、爬虫常用的数据解析分类:
  • 正则表达式(万金油)
  • Beautiful Soup
  • xpath方法(最常用)
2、爬虫数据解析原理概述

其实聚焦爬虫中关注的局部文本内容,通常是在页面HTML源码中的标签之间或者标签对应的属性中。

  • 进行指定标签的定位
  • 标签或者标签对应的属性中存储的数据值进行提取解析

正则表达式

1、概要

正则表达式,大家应该听得很熟了,那它到底是什么,为什么爬虫中经常使用,那就一看究竟。

正则表达式(regular expression)描述了一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。通俗理解:就是使用一种规则性的表达式来寻找文本字符串中通用的数据。

这里博主为了方便大家快速入门,只会对基础的语法知识进行讲解,如要进阶还需查阅更多官网文档。

2、常见语法

正则表达式包括普通字符和特殊字符,而这里的特殊字符其实就是元字符,因此本文主要对元字符进行简单讲解。

2.1、点(.

点(.)可以匹配所有字符:匹配出换行符以外的任意单个字符(按行匹配)

示例

# coding  : utf-8
# fun     : 正则表达式demo
# @Author : Labyrinthine Leo
# @Time   : 2021.02.01

import re

content = """苹果是绿色的
橙子是橙色的
香蕉是黄色的
乌鸦是黑色的
"""

p = re.compile(r'.色')
for one in p.findall(content):
    print(one)

注意re模块是使用正则表达式的python官方库,在使用之前需要进行import,其中re.compile()表示对正则表达式进行编译,将普通的字符串编译为可通配的正则表达式。p.findall(content)用于在文本中通过表达式进行匹配数据。结果如下:

爬虫入门—数据解析基础之正则表达式_第3张图片

2.2、星号(*

星号(*)重复匹配任意次:表示匹配前面的子表达式任意次,包括0次

示例

# coding  : utf-8
# fun     : 正则表达式demo
# @Author : Labyrinthine Leo
# @Time   : 2021.02.01

import re

content = """苹果,是绿色的
橙子,是橙色的
香蕉,是黄色的
乌鸦,是黑色的
猴子,
"""

p = re.compile(r',.*')
for i in p.findall(content):
    print(i)

解析',.*'表示匹配前面一个字符是全角逗号,后面紧接着多个字符,可以发现结果都是按行匹配的。结果如下:

爬虫入门—数据解析基础之正则表达式_第4张图片

2.3、加号(+

加号(+)重复匹配多次:表示匹配前面的子表达式一次或多次,不包括0次(用法同上)

2.4、花括号({}

花括号({})匹配指定次数:表示前面的字符匹配指定的次数,其表示范围(最小次数和最大次数)

示例

# coding  : utf-8
# fun     : 正则表达式demo
# @Author : Labyrinthine Leo
# @Time   : 2021.02.01

import re

content = """
红彤彤,绿油油,黑乎乎,绿油油油
"""
p = re.compile(r"绿油{3,4}")
for i in p.findall(content):
    print(i)

解析'绿油{3,4}'表示匹配绿字且紧接着的字出现最少3次最多4次的字符串,符合的只有绿油油油绿油油油油。结果如下:

爬虫入门—数据解析基础之正则表达式_第5张图片

2.5、问号(

问号()匹配0或1次:表示前面的字符匹配0或1次,等价于{0,1}

2.6、贪婪模式和非贪婪模式

假设我们需要将下面字符串中所有的html标签提取出来:

source = 'Title'

得到这样的列表:

['','',''</span><span class="token punctuation">,</span><span class="token string">'']

于是我们使用以下代码:

import re
p = re.compile(r'<.*>')
print(p.findall(source))

出现的匹配结果如下:

['Title']

我们代码中r'<.*>'表示匹配所以包含左右尖括号,中间含任意个字符的字符串,即我们想要的html标签,但是匹配的结果与我们预想的并不一样,这是为何呢?因为我们前面讲述的*+?都是贪婪性质的,所谓贪婪,是指其尽可能匹配更多的字符内容。而在这里我们想要的是让其一个标签一个标签的匹配,那就需要非贪婪模式,非贪婪模式其实就在匹配次数后加?即可,这里的话我们使用r'<.*?>'会发现即可将标签一个一个匹配出来。

示例

# coding  : utf-8
# fun     : 正则表达式demo
# @Author : Labyrinthine Leo
# @Time   : 2021.02.01

import re

source = 'Title'
p = re.compile(r'<.*?>')
print(p.findall(source))

结果如下:

爬虫入门—数据解析基础之正则表达式_第6张图片

2.7、反斜杠(\

反斜杠(\)对元字符转义:在正则表达式中有多种用途

  1. 比如说,点表示匹配任意单个字符,如果我们本身需要匹配点这个字符,则需要使用其进行转义,示例:
# coding  : utf-8
# fun     : 正则表达式demo:反斜杠转义
# @Author : Labyrinthine Leo
# @Time   : 2021.02.01

import re

content = """
苹果. 是绿色的
橙子. 是橙色的
香蕉. 是黄色的
乌鸦. 是黑色的
"""
p = re.compile(r'.*\.')
for i in p.findall(content):
       print(i)

结果

爬虫入门—数据解析基础之正则表达式_第7张图片

  1. 反斜杠后面接一些字符,表示匹配某种类型的单个字符:
  • \d 匹配0-9之间任意一个数字字符,等价于表达式 [0-9]
  • \D 匹配任意一个不是0-9之间的数字字符,等价于表达式 [^0-9]
  • \s 匹配任意一个空白字符,包括 空格、tab、换行符等,等价于表达式 [\t\n\r\f\v]
  • \S 匹配任意一个非空白字符,等价于表达式 [^ \t\n\r\f\v]
  • \w 匹配任意一个文字字符,包括大小写字母、数字、下划线,等价于表达式 [a-zA-Z0-9_]注意:缺省情况也包括 unicode文字字符,如果指定 ASCII码标记,则只包括ASCII字母。示例
# coding  : utf-8
# fun     : 正则表达式demo:多行匹配
# @Author : Labyrinthine Leo
# @Time   : 2021.02.01

import re

source = """
王亚辉
tony
刘文典
"""

p = re.compile(r'\w{2,4}',re.A) # re.A参数表示匹配ASCII字符
print(p.findall(source))

结果

爬虫入门—数据解析基础之正则表达式_第8张图片

  • \W 匹配任意一个非文字字符,等价于表达式 [^a-zA-Z0-9_]
2.8、方括号([]

方括号([])匹配单个字符:即匹配其中包含的字符,如[abc]可以匹配abc中的任意一个字符;[a-z]匹配范围内的字符;[^a-z]表示非小写字母。

2.9、起始位置和单行、多行模式

^表示匹配文本的起始位置,正则表达式中可以设定单行模式和多行模式。如果是单行模式,表示匹配整个文本的开头位置;如果是多行模式,表示匹配文本每行的开头位置。

示例

# coding  : utf-8
# fun     : 正则表达式demo:多行匹配
# @Author : Labyrinthine Leo
# @Time   : 2021.02.01

import re

content = """
001-苹果价格-60,
002-橙子价格-70,
003-香蕉价格-80,
"""

# 欲匹配编号,如果使用'\d+'则会将价格也匹配到,所以要匹配开头位置的信息
p = re.compile(r'^\d+', re.M) # 添加开头信息标识符,M表示MULTILINE,多行模式
print(p.findall(content))

结果

爬虫入门—数据解析基础之正则表达式_第9张图片

$ 表示匹配文本的结束位置,单行多行同上,如\d+$

2.10、括号(()):组选择

括号(())称之为正则表达式的组选择,即从正则表达式匹配的内容里面扣取出其中的某些需要的部分。

示例

# coding  : utf-8
# fun     : 正则表达式demo:组选择
# @Author : Labyrinthine Leo
# @Time   : 2021.02.01

import re

content = """
苹果,是绿色的
橙子,是橙色的
香蕉,是黄色的
乌鸦,是黑色的
"""

p = re.compile(r'^(.*),', re.M)
for i in p.findall(content):
    print(i) # 打印的是组选择

结果

爬虫入门—数据解析基础之正则表达式_第10张图片

:如果多行匹配的多个组,则每一行都是一个组选择的元组

示例

# coding  : utf-8
# fun     : 正则表达式demo:多行多个组选择
# @Author : Labyrinthine Leo
# @Time   : 2021.02.01

import re

content = """
张三,手机号码15945678901
李四,手机号码13945677701
王二,手机号码13845666901
"""

p = re.compile(r'^(.+),.+(\d{11})', re.MULTILINE)
for one in  p.findall(content):
    print(one)

结果

爬虫入门—数据解析基础之正则表达式_第11张图片

2.11、正则表达式切割字符串

示例

# coding  : utf-8
# fun     : 正则表达式demo:切割字符串
# @Author : Labyrinthine Leo
# @Time   : 2021.02.01

import re

names = '关羽; 张飞, 赵云,   马超, 黄忠  李逵'
namelist = re.split(r'[;,\s]\s*', names)
print(namelist)

结果

爬虫入门—数据解析基础之正则表达式_第12张图片

2.12、匹配换行符

前面说过,点(.)不能匹配换行符,如果我们使用时想让其匹配换行符,可以在compile()方法中添加re.DOTALL参数。

2.13、匹配模式替换
  1. 使用sub方法进行替换

示例

# coding  : utf-8
# fun     : 正则表达式demo:sub方法模式替换
# @Author : Labyrinthine Leo
# @Time   : 2021.02.01

import re

names = '''
下面是这学期要学习的课程:
点击这里,边看视频讲解,边学习以下内容
这节讲的是牛顿第2运动定律
'''
newStr = re.sub(r'/av\d+?/', '/cn345677/', names)
print(newStr)

结果

爬虫入门—数据解析基础之正则表达式_第13张图片

  1. 使用指数函数替换

示例

# coding  : utf-8
# fun     : 正则表达式demo:指数函数模式替换
# @Author : Labyrinthine Leo
# @Time   : 2021.02.01

import re

names = '''
下面是这学期要学习的课程:
点击这里,边看视频讲解,边学习以下内容
这节讲的是牛顿第2运动定律
点击这里,边看视频讲解,边学习以下内容
这节讲的是毕达哥拉斯公式
点击这里,边看视频讲解,边学习以下内容
这节讲的是切割磁力线
'''
# 替换函数,参数是 Match对象
def subFunc(match):
    # Match对象 的 group(0) 返回的是整个匹配上的字符串
    src = match.group(0)

    # Match对象 的 group(1) 返回的是第一个group分组的内容
    number = int(match.group(1)) + 6
    dest = f'/av{number}/'

    print(f'{src} 替换为 {dest}')

    # 返回值就是最终替换的字符串
    return dest

newStr = re.sub(r'/av(\d+?)/', subFunc , names)
print(newStr)

结果

爬虫入门—数据解析基础之正则表达式_第14张图片


临渊羡鱼不如退而结网
创作不易,如果您觉得这篇文章对你有用,可以点个赞,算是对笔者的支持和激励!这里是Leo的博客城堡,以Python为核,ML&DL为主,泛之形形色色,输寥寥拙见,摄浮光掠影,讲三两故事。临渊羡鱼,不如退而结网,持续干货输出,有趣的灵魂值得你的关注!
原文可以去笔者的github主页:https://github.com/LabyrinthineLeo/Yxs_Git_Learning_repos查看(如果可以,点个star也无妨呀,嘿嘿)。


爬虫入门—数据解析基础之正则表达式_第15张图片


你可能感兴趣的:(Spider入门,python,爬虫,正则表达式)