前言:
提起python内置re模块,就会想到正则表达式,本期给大家带来正则表达式的相关语法和内置方法的使用,还有两个使用re模块提取数据的案例,供大家参考。
正则表达式:
元字符:
元字符 . 匹配任意1个字符(除了\n) [] 匹配[]中列举的字符 \d 匹配数字,0-9 \D 匹配非数字 \s 匹配空白,即空格,tab键,换行 \S 匹配非空白,(数字、英文字符、特殊符号) \w 匹配单词字符,即a-z,A-Z,0-9 \W 匹配非单词字符 * 匹配前一个字符出现0次或者无限次,即可有可无 + 匹配前一个字符出现1次或者无限次,即至少有1次
re模块:
1.re.match
match()用于查找字符串的头部,它是一次匹配,只要找到了一个匹配结果就返回,而不是所有匹配的结果,形式如下:
match(pattern, string[ , flag])
import re pattern='python' string='pythonhhhjjsajidgpythonasdjjsk' result=re.match(pattern,string) print(result) #<re.Match object; span=(0, 6), match='python'>匹配的结果
其中pattern是正则规则字符串,string是待匹配的字符串,flag是可选参数,
当匹配成功时返回一个match对象,如果没有,则返回None。
2.re.search
search()用于查找字符串的任何位置,它也是一次匹配,只要找到一个结果就返回,而不是查找所有匹配的结果,它的形式如下:
search(pattern, string[ , flag])
#导入模块 import re str='one12two2three3' result=re.search('\d+',str) print(result) #search()函数用来查找第一个出现匹配的下标,返回一个正则对象 print(result.group()) #用group()函数用来返回之前抽出来的值 """ <re.Match object; span=(3, 5), match='12'> 12 """
匹配成功时返回一个match对象,如果没有匹配上,则返回None。
3.re.findall
上述两种方法都是一次匹配,大多数时候,我们需要搜索整个字符串,获得所有匹配的结果。findall形式如下:
findall(pattern, string, [ ,flag])
import re str='one1two2three3' result=re.findall('\d+',str) print(result) result=re.findall('\D+',str) print(result) #d是数字,D是英文,返回一个列表 """ ['1', '2', '3'] ['one', 'two', 'three'] """
findall()以列表形式返回全部匹配的子串,如果没有匹配,则返回一个空列表。
4.re.split
split()能够将匹配的子串分割后返回列表,它的使用形式如下:
split(pattern , string [ ,maxsplit, flags])
import re pattern='\d+' string='pythonasdkjasd464654adhuiaghsdk564654akjsdhkashdkja' result=re.split(pattern, string ,maxsplit= 2) print(result) """ ['pythonasdkjasd', 'adhuiaghsdk', 'akjsdhkashdkja'] """
这里的maxsplit默认为0表示全部切割,
1 代表切割1次
2 代表切割2次
5.re.sub
sub()用于替换,使用形式如下:
sub(pattern , rep1, string[ , count, flags])
第一个参数是正则表达式,第二个参数是要替换成的字符,第三个为原字符串,第四个参数为可选项,代表最多替换次数,默认为全部替换。
import re phone='123-456-789' new_phone=re.sub('\D','',phone) print(new_phone) #结果为:123456789
flags re.I 匹配对大小写不敏感 re.L 做本地化识别匹配 re.M 多行匹配,影响^和$ re.S 使.匹配包括换行在内的所有字符 re.U 根据Unicode字符集解析字符,这个标志影响\w,\W,\b,\B re.X 该标志通过给于更灵活的格式以便你将正则表达式写得更于理解
案例一:提取双色球中奖信息
网页地址:https://sds.yiqicai.com/detail/1001/23108提取中奖日期,全国销量,累计奖池,大奖号码。
import re import time import requests import bs4 import random from PreventSpider import headers_list from bs4 import BeautifulSoup #导入模块 def getData(your_url): #构建请求头 headers={ 'User-Agent':random.choice(headers_list), 'Host': 'sds.yiqicai.com', 'Cookie': '6140d6b0ad9f4c98842cf49e8b7933c3 = WyIyNTY0MDkyNDY4Il0;Hm_lvt_5b67d7ffc244beea7a0e6dafd608d392 = 1695119057;Hm_lpvt_5b67d7ffc244beea7a0e6dafd608d392 = 1695119057', } #获取响应体对象 response=requests.get(url=your_url,headers=headers) # print(response.text) honour_number=re.findall('</span> <b class="c-red" data-v-6697473c>(.*?)</b></dd>',response.text)[0] time=re.findall('aq,issueDay:"(.*?)",issueWeek:m,resultTime',response.text)[0] jiangchi=re.findall('累计奖池:</span> <b class="c-red" data-v-6697473c>(.*?)</b>',response.text)[0] first=re.findall('<em data-v-6697473c>(.*?)</em>',response.text) print('本期开奖时间:',time) print('本期奖池为销量为:',honour_number,'注') print('累计奖池:',jiangchi,'元') print('本期一等奖为:',end=' ') #输出大奖号码 for f in first: print(f,end=' ') if __name__=='__main__': getData('https://sds.yiqicai.com/detail/1001/23108?frm=C_PC360')
案例二:提取斗破苍穹小说
提取该文章信息:
import re import requests import random from PreventSpider import headers_list import time f=open('D:\python爬虫\爬虫新手课程\data.txt','a+') def getData(your_url): headers={ 'User-Agent':random.choice(headers_list) } response=requests.get(url=your_url,headers=headers) #检测网页状态码 if (response.status_code == 200): #print(response.text) #匹配文章 contents=re.findall('<p>(.*?)</p>',response.text,re.S) for content in contents: #将非截断空白替换为空 item=content.replace(' ','') # f.write(item) """ 字符串有些无法输入,需要改代码,如下: """ print(item) #写入文件 f.write(item.encode('gbk','ignore').decode('gbk')) if __name__=='__main__': #提取一百页数据 for page in range(100): urls=[f'https://www.51shucheng.net/wangluo/doupocangqiong/{page}.html'] for url in urls: try: getData(url) time.sleep(1) except 'page' as e: pass f.close()
回到所创建的txt文件查看所爬取的文章信息,可惜的是有些文字做了字体反扒,后续需要进行字体反扒的破解,后面文章再发布破解思路。