@
目录
- 前言
- 导航
- 正则表达式介绍
- 正则表达式基本语法
- re库的使用
- 常用函数
- 案例源码
- 运行截图
- 共勉
- 博客
前言
本文原本是想通过分享一个爬取东方财富网案例,来介绍parsel解析库的使用,没想到硬生生的写成了正则表达式的详细使用,想学习正则表达式的的小伙伴们可以来看下。
导航
- 爬取小说案例-BeautifulSoup教学篇
- 爬取二手房案例--parsel教学篇(CSS选择器)
- 爬取美国公司案例-parsel库教学篇(Xpath的详细使用)
- 爬取东方财富网-parsel教学篇(正则表达式的详细使用+实例)
- 爬取QQ音乐的评论-JSON库的详细使用
正则表达式介绍
正则表达式是一种用于匹配字符串中字符组合的模式。不管是在Linux,windows系统中,亦或是python,javascript,go等等语言中,都有可能用到正则表达式来匹配字符串。它就像是一种高级的文本搜索和处理工具,可以帮助你在大量文本中快速找到符合特定规则的内容,或者对文本进行复杂的替换、提取等操作。例如,你可以使用正则表达式来验证用户输入的电子邮件地址是否符合格式要求,或者从一段网页源代码中提取所有的链接。今天我们就是从爬取到东方财富网的数据通过正则表达式来进行分别提取出来。
正则表达式基本语法
字符匹配 | 解释 |
---|---|
\d | 匹配任意一个数字 即0-9 |
\D | 匹配非数字,与\d相反 |
\s | 匹配任何空白字符,包括空格、制表符\t、换行符\n等 |
\S | 匹配任何非空白字符 |
\w | 匹配任何字母和数字以及下划线_ |
\W | 匹配任何非数字和字母以及下划线_。 |
\b | 匹配单词和非单词的边界。例如:\w+\b-->匹配整个单词 |
量词 | 解释 |
---|---|
. | 匹配任意一个字符 |
* | 匹配前0个或多个元素(可有可无) |
+ | 匹配前一个或多个元素 |
? | 匹配前面的元素零次或一次(可有[有只出现一次]可无[匹配为空]) |
特殊字符 | 解释 |
---|---|
^ | 匹配字符串开头 |
$ | 匹配字符串结尾 |
| | 匹配左右任意一个表达式 |
匹配前面的元素恰好n次 | |
匹配前面的元素至少n次 | |
匹配前面的元素至少n次且最多m次 | |
() | 捕获组,用于捕获匹配的内容 |
为了更好的理解上面各个正则表达式的语法,下面举一些例子: |
#这里只是举一些正则表达式的语法,后面有这些实际应用的例子。\d{6}:匹配6个连续长度数字的字符,例如:123456^\D+$:匹配整个字符串都由非数字组成的字符,例如:用于用户名验证,要求用户名不能包含数字\S+:根据非空白字符来查找字符,例如:"python is excellent ",查找的结果为"python","is","excellent"https?://([^/]+):提取URL中的域名部分。例如:"https://test.com/result/index.html",匹配域名test.com\b\d{4}-\d{2}-\d{2}\b:匹配日期YYYY-MM-DD格式,如2019-04-25\b\w+\.(jpg|png)\b:匹配以jpg和png为后缀的文件(.*?):非贪婪匹配-->尽可能匹配少的字符
re库的使用
Python 的 re 库(正则表达式库)是一个功能强大的字符串处理工具,它提供了对正则表达式的支持,允许开发者进行复杂的字符串搜索、替换和匹配操作。
常用函数
常用函数 | 解释 |
---|---|
re.match(pattern, string, flags=0) | 用于检查字符串是否以指定的正则表达式模式开头,如果匹配成功返回匹配对象,否则返回 None |
re.search(pattern, string, flags=0) | 扫描整个字符串,返回第一个匹配成功的结果 |
re.findall(pattern, string, flags=0) | 用于在整个字符串中查找所有匹配正则表达式的子串,并返回一个列表 |
re.sub(pattern, repl, string, count=0, flags=0) | 使用 repl 替换 string 中所有与 pattern 匹配的子串,返回替换后的字符串 |
re.compile(pattern, flags=0) | 将正则表达式模式编译成一个正则表达式对象 |
- pattern:正则表达式,匹配的模式
- string:要匹配的源字符串
- flags=0:默认的匹配标志,可省略,下面是一些常见的匹配标志
- re.I/re.IGNORECASE:忽略大小写
- re.M/re.MULTILINE:多行模式,^和$将匹配每一行的开始和结束,而不仅仅是整个字符串的开始和结束
- re.S/re.DOTAIL:单行匹配,使 . 匹配包括换行符在内的所有字符
- re.X/re.VERBOSE:允许正则表达式使用空白和注释来增强可读性
- re.A/re.ASCII:对于 \w、\W、\b、\B 等特殊转义字符进行 ASCII 匹配
- repl:用于替换匹配的字符串
- count=0:表示替换次数的最大次数,默认为零,表示替换所有匹配项
下面是一些这些函数的使用例子:
import res_string = "520 I will Miss you whether you miss me or not 1314"pattern=r'\d+'
# data为匹配到的match对象,需要使用group()方法来获取其中的内容
data=re.match(pattern,s_string)
print(data.group())
# 输出为:520pattern_findall = r'miss'
data_findall=re.findall(pattern_findall,s_string,re.IGNORECASE)
print(data_findall)
# 输出为:['Miss', 'miss']pattern_search = r'(\d{3}).*(\d{4})'
data_search=re.search(pattern_search,s_string)
print(data_search.group(1),data_search.group(2)) # 返回字符串
print(data_search.group(1,2)) # 返回元组
# 输出为:520 1314
# ('520', '1314')pattern_sub = r'\d+'
data_sub=re.sub(pattern_sub,'917',s_string)
print(data_sub) # 返回的是新的字符串,源字符串不变
print(s_string)
# 输出为:917 I will Miss you whenever you miss me or not 917
# 520 I will Miss you whenever you miss me or not 1314pattern_compile = re.compile(r'\bmiss you\b',re.IGNORECASE)
data_compile=pattern_compile.findall(s_string)
print(data_compile)
# 输出为:['Miss you']s_string = 'There are no shortcuts to any place worth going 123456'
pattern=re.compile(r'\d{6}')
data = pattern.findall(s_string)
print(data)
# 输出为:['123456']s_string = 'python is excellent '
pattern=re.compile(r'\S+')
data = pattern.findall(s_string)
print(data)
# 输出为:['python', 'is', 'excellent']s_string = 'https://test.com/result/index.html'
pattern=re.compile(r'https?://([^/]+)')
data=pattern.findall(s_string)
print(data)
# 输出为:['test.com']s_string = '2024-12-20 19:08:50'
pattern=re.compile(r'\b\d{4}-\d{2}-\d{2}')
data=pattern.findall(s_string)
print(data)
# 输出为:['2024-12-20']pattern = re.compile(r'(\b\w+\.(jpg|png)\b)')
s_string = 'image1.jpg image2.png image3.gif doc.word study.md'
data=pattern.findall(s_string)
print(data)
print([i[0] for i in data])
# 输出为:[('image1.jpg', 'jpg'), ('image2.png', 'png')]
# ['image1.jpg', 'image2.png']
- 进阶:更多进阶的正则表达式教程可以参考这个网站:RegexOne
- ps:当匹配到一些特殊字符的时候,比如() [ ] { } . 等,要用\进行转义,例如上面的提取域名的例子。
下面是一个爬取东方财富网中排名前一百的基金排行案例。
案例源码
import requests # 数据请求库
import parsel # 数据解析库
import re # 正则表达式库# 过滤函数 处理空字符串
def fiter_data(data):res=[item for item in data if item !=""]return res# 东方财富网url
url='https://fund.eastmoney.com/data/rankhandler.aspx?op=ph&dt=kf&ft=all&rs=&gs=0&sc=1nzf&st=desc&sd=2023-11-27&ed=2024-11-27&qdii=&tabSubtype=,,,,,&pi=1&pn=50&dx=1&v=0.6714046315345714'
# 请求头:user-agent-->浏览器信息(用于伪装浏览器),cookie-->会话标识,referer-->表明请求从那个页面发起的
headers={'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0','cookie':'qgqp_b_id=21ae41f99fecb474bee6e30b4530066c; st_si=25763365055282; st_asi=delete; ASP.NET_SessionId=xl3dc42fk2zkk44sxgkvit2s; websitepoptg_api_time=1732672471290; _adsame_fullscreen_14694=1; fund_registerAd_1=1; st_pvi=43079868354789; st_sp=2024-11-25%2010%3A19%3A12; st_inirUrl=https%3A%2F%2Fcn.bing.com%2F; st_sn=7; st_psi=2024112709544783-112200312936-9175803359','referer':'https://fund.eastmoney.com/data/fundranking.html'}
response=requests.get(url=url,headers=headers)
# 将正则表达式编译成一个正则表达式对象
pattern = re.compile(r'var rankData = {datas:\[\"(.*?)\"].*')
# 查找对应的字符
data=pattern.findall(response.text)
# 返回是个列表,所以需要取列表中的第一个字符串
data=data[0]
# 利用","进行分割
data=data.split('","')
# 遍历
for i in data:res=i.split(',')# 过滤其中的空白字符res=fiter_data(res)print(f'基金代码:{res[0]},基金名称:{res[1]},基金ID:{res[2]},日期:{res[3]},单位净值:{res[4]},累计净值:{res[5]},日增长率:{res[6]},周增长率:{res[7]},月增长率:{res[8]}')
运行截图
共勉
与其等风来,不如追风去!
博客
- 本人是一个渗透爱好者,不时会在微信公众号(laity的渗透测试之路)更新一些实战渗透的实战案例,感兴趣的同学可以关注一下,大家一起进步。
- 之前在公众号发布了一个kali破解WiFi的文章,感兴趣的同学可以去看一下,在b站(up主:laity1717)也发布了相应的教学视频。