0%

python爬虫三

python爬虫之re解析库(一)

  • 这次主要解释爬虫的解析器的部分用法,解析数据确实是爬虫中的重要一环,请求数据之后,便是要找到我们想要的数据,也可以这么认为这是过滤环节,去除无用的信息,并获取自己想要的数据,其实有点类似于字符串的处理,这里主要简单说明一下re库的基本操作

re库

  • python中自带的字符串处理库
优缺点 评价
优点 自带官方库,对于大部分的字符串的处理都能游刃有余,处理小量数据没有问题,速度快
缺点 需要制定比较繁琐的规则,不能保持爬虫的时效性,规则需要频繁改写
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import re

def parse():

pattern=re.compile('.*?<br />(.*?)#.*?<br />',re.S)
#re.S表示换行匹配,不受行数限制,python常用pattern来封装表达式规则,极大方便了调用

result=re.findall(pattern,datas)
#表示寻找Html里面的所有匹配规则的字符串

print(type(result))
#打印值返回型
for results in result:
#列表的遍历
with open ("ip.txt","a",encoding="utf-8") as f:
#将结果保存到列表中.以text的格式
f.write("{}\n".format(results))
print("Download successfully!")

return None
  • 这里面使用了re.findall对整个文本进行处理,关于re库的具体使用方法,可以到网上阅读.这里我列出我使用的几种用法:
函数方法 参数 说明
re.sub (pattern,replace-strings,strings,flags) 字符串的替换
re.compile (flags) 封装过滤规则,返回封装对象patttern
re.search (pattern,strings,flags) 搜索整个字符串,并返回匹配到的第一个结果
re.match (pattern,strings,flags) 字符串开始进行搜索,规则要从第一个字符开始,否则返回None
re.findall (pattern,strings,flags) 搜索整个字符串,并返回所有符合匹配的结果的一个列表
re.finditer (pattern,strings,flags) 与上面的findall的用法一样,但是返回一个迭代器
  • flags-正则表达式修饰符,可以复合使用:option1|option2
参数 说明
re.I 使匹配字符对大小写不敏感
re.S 匹配换行符在内的字符
re.U 根据unicode匹配字符
re.X 是匹配规则更加容易理解
  • pattern 匹配规则,对于学习过其他语言的re库来说,其实匹配规则都是大同小异的,只是使用方法略微不同了

  • 常用元字符

参数 说明
\d 匹配数字
\s 匹配空白符
^ 匹配字符串的开始
$ 匹配字符串的结束
\b 匹配单词的开始或结束
. 匹配除换行符以外的字符
\w 匹配字母或数字或下划线或汉字
  • 常用限定符
参数 说明
? 重复零次或一次
+ 重复一次或更多次
* 重复零次或者更多次
\d{m,n} 重复m次到n次
\d{n} 重复匹配数字n次
  • 懒惰限定符,顾名思义,就是为了简明繁琐的规则而诞生的限定符
参数 说明
?? 重复0次到1次
.*? 重复任意次,少重复
*? 重复任意次直至匹配不出来,多重复
  • (.*?)代表匹配尽可能少的字符,无论字母还是数字,比如某些url地址等,直接来个如下代码
1
2
3
4

pattern = re.compile(r'.*?<br />(.*?)#.*?<br />',re.S)

res = re.findall(pattern,htmls)

  • 零宽断言,是一种零宽度匹配的,不会保存在匹配结果中,仅仅是代表一个位置.
代码 说明
?= 零宽度正预测先行断言,即确定后面位置,前接匹配规则
?<= 零宽度正回顾后发断言,即确定前面位置,后接匹配规则
?! 零宽度负预测先行断言,否定后面的位置,在执行前接规则
?<! 零宽度负回顾后发断言,否定前面的位置,再执行后接规则
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import re

strings='个人邮箱是:x789236@qmail.com,个人信用代码是:4456897Q,个人名称是:rester'

#确定后面的位置是个人信用
res1=re.findall(r"个人邮箱是:(.*?)(?=,个人信用)",strings)
print(res1)

#确定前面的位置是代码
res2=re.findall(r"(?<=代码是:)(.*?)(?=,)",strings)
print(res2)

#否定后面位置是个人名称,而是个人信用
res3=re.findall(r'个人邮箱是:(.*?)(?!,个人名称是)(?=,个人信用)',strings)
print(res3)

#否定前面是后缀cn,确定是.com
res4=re.findall(r'(?<!.cn,)(?<=.com,)(.*?)(?=,个人名称是)',strings)
print(res4)

#运行结果:
['x789236@qmail.com']
['4456897Q']
['x789236@qmail.com']
['个人信用代码是:4456897Q']
-------------本文结束感谢您的阅读-------------