python爬虫之正则表达式(用在其他地方也可)
1. 常用的匹配规则
### 常用的匹配规则 # \w 匹配字母、数字及下划线 # \W 匹配不是字母、数字及下划线的字符 # \s 匹配任意空白字符,等价于[\t\n\t\f] # \S 匹配任意非空字符 # \d 匹配数字,等价于[0-9] # \D 匹配任意非数字的字符 # \A 匹配字符串开头 # \Z 匹配字符串结尾,如果存在换行,只匹配到换行前的结束字符串 # \z 匹配字符串结尾,如果存在换行,同时还会匹配换行符 # \G 匹配最后匹配完成的位置 # \n 匹配一个换行符 # \t 匹配一个制表符 # ^ 匹配一行字符串的开头 # $ 匹配一行字符串的结尾 # . 匹配任意字符,除了换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符 # [...] 用来匹配一组字符的任意一个字符 # [^...] 用来匹配不在[]中的字符 # * 匹配0个或多个表达式 # + 匹配1个或多个表达式 # ? 匹配0个或1个前面的正则表达式定义的片段,非贪婪方式 # {n} 精确匹配n个前面的表达式 # {n,m} 匹配n到m次由前面正则表达式定义的片段,贪婪方式 # a|b 匹配a或b # () 匹配括号内的表达式,也表示一个组
2. match方法,传入表达式和字符串进行匹配
1 ## match方法,传入表达式和字符串进行匹配 2 import re 3 4 content = 'I am shaobo, my number is 1383838438. regex Demo' 5 result = re.match('^I\s\D\D\s[a-zA-Z]+.*\d', content) 6 print(result) 7 # 正则匹配到的内容 8 print(result.group()) 9 # 匹配到的内容所在的位置 10 print(result.span())
3. 贪婪匹配和非贪婪匹配
1 # 贪婪匹配和非贪婪匹配 2 import re 3 4 content = 'I am shaobo, my number is 13838\n38438. regex Demo' 5 # 贪婪匹配,一直匹配到最后一个'\d',即数字字符才结束(如果遇到换行符,则结束) 6 result = re.match('^I.*\d\s(.*)\.', content) 7 # 非贪婪匹配,匹配到第一个'\d',即数字字符就结束 8 result2 = re.match('^I.*?\d', content) 9 print(content) 10 print(result.group(1)) 11 print(result2.group())
4. 修饰符
1 ## 修饰符,上个例子我们用\s匹配到了换行符,才使正则表达式可以匹配换行符后的内容,通过修饰符re.S使.包含匹配换行符 2 # re.I 使匹配对大小写不敏感 3 # re.L 做本地化识别(locale-aware)匹配 4 # re.M 多行匹配,影响^和$ 5 # re.S 使.匹配包括换行在内的所有字符 6 # re.U 根据Unicode字符集解析字符,这个标志影响\w、\W、\b和\B 7 # re.X 该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解 8 import re 9 10 content = 'I am shaobo, my number is 13838\n38438. regex Demo' 11 result = re.match('^I.*?\d(.*)re', content, re.S) 12 print(result.group(1))
5. 转义匹配
1 ## 转义匹配,当内容包括'()'、'.'等字符时,可通过转义字符匹配到所看到的内容 2 import re 3 4 content = '(dmr哇)www.baidu.com' 5 result = re.match('\(.*?\)www\.baidu\.', content) 6 print(result.group()) 7 8 9 # 输出内容 10 ''' 11 (dmr哇)www.baidu. 12 '''
6. search方法
1 ## search方法,match从开头开始匹配,如表达式匹配不到字符串的开头内容,则匹配失败,返回None 2 ## search方法通过扫描字符串来进行匹配,返回第一个匹配到的结果 3 import re 4 5 content = 'I am shaobo, my number is 13838\n38438. regex Demo' 6 result = re.match('my.*?\.', content, re.S) 7 result2 = re.search('my.*?\.', content, re.S) 8 9 print(result + '\n' + result2) 10 11 12 # 输出内容 13 ''' 14 None 15 <re.Match object; span=(13, 38), match='my number is 13838\n38438.'> 16 '''
7. findall方法
## findall方法,前面的match和search方法都是匹配到第一个符合表达式的内容,findall方法可以把所有符合表达式的内容都提取出来 import re html = ''' <h2 clall="title">经典老歌</h2> <ul> <li data="1">沧海一声笑</li> <li data="2">光辉岁月</li> <li data="3">但愿人长久</li> <li data="4">丁香花</li> </u> ''' result = re.findall('<li.*?=(.*?)>(.*?)</li>', html, re.S) print(result) for item in result: print(item[0], item[1]) # 输出内容 ''' [('"1"', '沧海一声笑'), ('"2"', '光辉岁月'), ('"3"', '但愿人长久'), ('"4"', '丁香花')] "1" 沧海一声笑 "2" 光辉岁月 "3" 但愿人长久 "4" 丁香花 '''
8. sub方法
## sub方法,匹配内容进行修改 import re content = '2dlfiwe3lk59lk388ji' result = re.sub('\d+', '', content) print(result) # 输出内容 ''' dlfiwelklkji '''
9. compile方法
1 ## compile方法,将正则表达式编译成对象,从而进行复用 2 import re 3 4 time1 = '2020-3-12 12:23' 5 time2 = '2020-2-12 19:53' 6 time3 = '2020-9-12 11:03' 7 c = re.compile('\d{2}:\d{2}') 8 result1 = re.sub(c, '', time1) 9 result2 = re.sub(c, '', time2) 10 result3 = re.search(c, time2) 11 print(result1, result2, result3.group()) 12 13 14 # 输出内容 15 ''' 16 2020-3-12 2020-2-12 19:53 17 '''
10. 用正则表达式提取豆瓣电影top250
1 ## 用正则表达式提取豆瓣电影top250 2 import requests, re, json, time 3 4 5 def get_page(url): 6 7 headers = { 8 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36' 9 } 10 response = requests.get(url=url, headers=headers) 11 if response.status_code == 200: 12 return response.text 13 else: 14 exit("访问页面失败") 15 16 17 def parser_page(html): 18 pattern = re.compile( 19 '<div class="item.*?<img.*?src="(.*?)".*?<a href="(.*?)".*?title">(.*?)</span>.*?<p class.*?:(.*?) .*?:(.*?)<.*?(\d.*?)&.*?/.*?;(.*?)&.*?/.*?;(.*?)\n.*?pro.*?>(.*?)<.*?in.*?>(.*?)<', re.S) 20 items = re.findall(pattern, html) 21 22 for item in items: 23 yield { 24 'img': item[0], 25 'details': item[1], 26 'name':item[2], 27 'director':item[3], 28 'actor':item[4], 29 'time':item[5], 30 'nation':item[6], 31 'type':item[7], 32 'score':item[8], 33 'introduction':item[9], 34 } 35 return items 36 37 def save_file(data): 38 with open('doubanTOP250.txt', 'a', encoding='utf-8') as f: 39 f.write(json.dumps(data, ensure_ascii=False) + '\n') 40 41 def main(start): 42 url = 'https://movie.douban.com/top250?start=' + str(start) 43 html = get_page(url) 44 data = parser_page(html) 45 for item in data: 46 print(item) 47 save_file(item) 48 49 50 if __name__ == '__main__': 51 for i in range(10): 52 start = i * 25 53 main(start)
静静的学习一阵子儿...