Python爬虫(一)----正则表达式
博客分享:
To strive , to seek , to find and not to yield.
要奋斗,要探索,要去发现,而不是屈服。
一、准备库方法
window10安装方法:
1、安装python并添加环境变量 (百度方法很多)
(添加环境变量的作用:想运行python时,在命令提示符窗口直接输入python就可以运行。
不添加环境变量:想运行python时,还需要在命令提示符窗口先进入python安装目录在运行python,相比添加环境变量来说繁琐许多。)
2、win+r
3、输入pip install 库名称
二、正则表达式
1、方法一:re.match()和re.search()
定义:
re.match()定义: re.match 尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回none
import re
print(re.match('www', 'www.runoob.com').span()) # 在起始位置匹配
print(re.match('com', 'www.runoob.com')) # 不在起始位置匹配
打印结果:
(0, 3)
None
re.search()定义: re.search 扫描整个字符串并返回第一个成功的匹配。
import re
s = '1102231990xxxxxxxx'
res = re.search('(?P<province>\d{3})(?P<city>\d{3})(?P<born_year>\d{4})',s)
print(res.groupdict())
打印结果:
{'province': '110', 'city': '223', 'born_year': '1990'}
re.match和re.search语法:
语法:re.match(pattern, string, flags=0) re.search(pattern, string, flags=0)
- pattern : 匹配的正则表达式
- string : 要匹配的字符串
- flags : 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。
re.match和re.search区别:
re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;而re.search匹配整个字符串,直到找到一个匹配。
import re
line = "Cats are smarter than dogs";
matchObj = re.match( r'dogs', line, re.M|re.I)
if matchObj:
print "match --> matchObj.group() : ", matchObj.group()
else:
print "No match!!"
matchObj = re.search( r'dogs', line, re.M|re.I)
if matchObj:
print "search --> searchObj.group() : ", matchObj.group()
else:
print "No match!!"
打印结果:
No match!!
search --> searchObj.group() : dogs
2、方法二:filter()过滤函数 lambda()匿名函数
定义:
定义:filter() 函数用于过滤序列,过滤掉不符合条件的元素,返回一个迭代器对象,如果要转换为列表,可以使用 list() 来转换。
该接收两个参数,第一个为函数,第二个为序列,序列的每个元素作为参数传递给函数进行判,然后返回 True 或 False,最后将返回 True 的元素放到新列表中。
import re
data_list = ['cat_1', 'dog_1', 'dog_2', 'cat_2', 'dog_3', 'cat_3'] # 原列表中既有dog也有cat, 并且无规律
new_data_list = list(filter(lambda x: re.match('dog.*', x) != None, data_list)) # 生成新列表
print(new_data_list)
打印结果:
['dog_1', 'dog_2', 'dog_3']
filter(function, iterable) 语法:
- function 判断函数。
- iterable 可迭代对象。
def is_odd(n):
return n % 2 == 1
tmplist = filter(is_odd, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
newlist = list(tmplist)
print(newlist)
输出结果 :
[1, 3, 5, 7, 9]
3、方法三:re.findall()函数
定义:
遍历所有字符串,将符合规则的字符串放到一个列表中,未匹配到返回空列表。
例:提取一片英文中的所有a开头三个字母的单词
1、re.findall('a..', text) #第一个为正则表达式 后边的为从哪里提取
提取出文本中的符合的有 'acd','a z','a ','ad '四种情况
2、为了防止2、3、4这种情况可以这样写
re.findall('a[a-z][a-z]', text)
3、提取'a'开头的三个字符的单词
re.findall(' a[a-z][a-z] ', text) 左右加两个空格 但是打印出来的左右都空格
4、re.findall('(a[a-z][a-z])', text) 加()就可以了
5、去重
result = re.findall('(a[a-z][a-z])', text)
result = set(result) //去重
4、 正则常用匹配符号
. | 表示一个任意字符 |
---|---|
[a-z] | 表示’a’到’z’之间字母 |
* | 表示有一个或多个或没有 例 a*:可以是空,可以是a,可以是aa,可以aaa |
+ | 表示有一个或多个,与’*‘区别就是’+'不能为空,例:a+可以是a,可以是aa,可以aaa |
\d | 表示所有的数字,一个[0-9] |
\D | 表示匹配所有非数字字符,相当于[^0-9] |
\d{2} | 表示匹配两个数字 |
\d{2,3} | 表示匹配二到三个数字 |
\w | 表示匹配包括下划线在内的任何数字和字母字符,相当于[a-zA-Z0-9] |
\W | 表示匹配包括除下划线在内的任何数字和字母字符,相当于[^a-zA-Z0-9] |
\s | 表示匹配任何空白字符,类似于[\t\n\r\f\v] |
\S | 表示匹配任何非空白字符,类似于[^\t\n\r\f\v] |
.* | 匹配任意字符 |
re.I | 匹配忽略大小写 |
re.S | 忽略换行的影响,整体进行匹配,如果不加re.S,则匹配第一行,如果没有从第二行重新开始匹配 |
^ | 非、取反,匹配出除[^]里面的字符, ^字符如果写到字符集里就是反取 |
5、贪婪匹配和非贪婪匹配 ?
- 非贪婪匹配:? 匹配到第一个满足的就返回
- 贪婪匹配:不加? 匹配到最后一个满足的才返回
import re
a = 'sdafad1asdf1'
r1 = re.findall(".*?1",a) #非贪婪 匹配到第一个1就返回
r2 = re.findall(".*1",a) #贪婪 匹配到最后一个才返回
print(r1)
print(r2)
打印结果:
['sdafad1', 'asdf1']
['sdafad1asdf1']
注:1是放在❓后面的。
6、字符集[ ]
import re
a = 'sda2fad113jdkg;33asld1l23f1'
r1 = re.findall("\d",a)
r2 = re.findall("[12]",a) #字符集 无序
print(r1)
print(r2)
打印结果:
['2', '1', '1', '3', '3', '3', '1', '2', '3', '1']
['2', '1', '1', '1', '2', '1']
import re
a = 'sda2fad113jdkg3312368asld1l23f1'
r1 = re.findall("\d",a)
r2 = re.findall("[123][456][789]",a) #字符集 匹配的第一个数要在[123]中,第二个数在[456]中,第三个数在[789]中,要连续
print(r1)
print(r2)
打印结果:
['2', '1', '1', '3', '3', '3', '1', '2', '3', '6', '8', '1', '2', '3', '1']
['368']
字母和‘+’ '+'表示和前边一个[]的属性一样多个匹配
import re
a = 'sda2fad113:jdkg3312368as:lddddd1l23f1'
r1 = re.findall("\d",a)
r2 = re.findall("[:][jld]+",a) #字符集无序
print(r1)
print(r2)
打印结果:
['2', '1', '1', '3', '3', '3', '1', '2', '3', '6', '8', '1', '2', '3', '1']
[':jd', ':lddddd']
7、数量词
import re
a = 'sdZa2fZad113:jdkg3312368as:ldZdddZd1l23f1'
r1 = re.findall("[a-zA-Z]{3,8}",a) #匹配3-8个
print(r1)
打印结果:
['sdZa', 'fZad', 'jdkg', 'ldZdddZd']
8、范匹配和精确匹配
import re
a = 'python1python2python3pythonnnnn'
r1 = re.findall(r'python\d',a)
r2 = re.findall(r'python(\d)',a)
print(r1)
print(r2)
打印结果:
['python1', 'python2', 'python3'] //范匹配
['1', '2', '3'] //精确匹配
例:匹配出网页中的内容
import re
a = '<a class="level-link"\
href="//www.bilibili.com/blackboard/help.\
html#%E4%BC%9A%E5%91%98%E7%AD%89%E7%BA%A7%E7%9B%B8%\
E5%85%B3" target="_blank"><i class="level l4"></i>\
</a><p class="text">直播就是废话特别多,还不如看其他的</p>\
//www.bilibili.com/blackboard/help </p>'
content1 = re.findall(r'</a><p class="text">(.*?)</p>',a) #精确非贪婪匹配,找到第一个</p>就返回
content2 = re.findall(r'</a><p class="text">(.*)</p>',a)#精确贪婪匹配,找到最后一个</p>才返回
content3 = re.findall(r'</a><p class="text">.*?</p>',a)#范匹配+非贪婪匹配
content4 = re.findall(r'</a><p class="text">.*</p>',a)#范匹配+贪婪匹配
print(content1)
print(content2)
print(content3)
print(content4)
打印结果:
['直播就是废话特别多,还不如看其他的']
['直播就是废话特别多,还不如看其他的</p> //www.bilibili.com/blackboard/help ']
['</a><p class="text">直播就是废话特别多,还不如看其他的</p>']
['</a><p class="text">直播就是废话特别多,还不如看其他的</p> //www.bilibili.com/blackboard/help </p>']
文章参考https://www.cnblogs.com/gufengchen/p/10913186.html
视频参考https://www.bilibili.com/video/BV1it411W77P
视频参考https://www.bilibili.com/video/BV1xs411x71b