Py007-01-09爬虫之数据解析以及re操作

数据解析

  1. 指定url
  2. 发请求
  3. 获取页面数据
  4. 数据解析
  5. 进行持久化

三种数据解析方式

  • 正则
  • bs4
  • xpath

正则re模块

用法回顾

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
26
27
28
29
单字符:
. : 除换行以外所有字符
[] :[aoe] [a-w] 匹配集合中任意一个字符
\d :数字 [0-9]
\D : 非数字
\w :数字、字母、下划线、中文
\W : 非\w
\s :所有的空白字符包,括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。
\S : 非空白
数量修饰:
* : 任意多次 >=0
+ : 至少1次 >=1
? : 可有可无 0次或者1次
{m} :固定m次 hello{3,}
{m,} :至少m次
{m,n} :m-n次
边界:
$ : 以某某结尾
^ : 以某某开头
分组:
(ab)
贪婪模式: .*
非贪婪(惰性)模式: .*?

re.I : 忽略大小写
re.M :多行匹配
re.S :单行匹配

re.sub(正则表达式, 替换内容, 字符串)

代码示例

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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#!/usr/bin/env python
#-*- encoding:utf-8 -*-
import re

# 提取python
key = 'javapythonc++php'
res =re.findall('python',key)
print(res) # ['python']

# 提取hello world
key = '<html><h1>hello world</h1></html>'
res =re.findall('<h1>(hello world)</h1>',key)
print(res) # ['hello world']

# 提取170
key = '我喜欢身高170的女孩'
res =re.findall('\d+',key)
print(res) # ['170']

# 提取 http 和 https
key = 'http://www.baidu.com and https://boob.com'
res =re.findall('https?',key)
res2 = re.findall('https{0,1}',key)
print(res,res2) # ['http', 'https'] ['http', 'https']

# 提取hit.
key = 'bobo@hit.edu.com'
res =re.findall('h.*\.',key) # ['hit.edu.']
print(res) # ['hit.edu.'] 贪婪模式(默认)尽可能多的提取数据
res2 =re.findall('h.*?\.',key)
print(res2) # ['hit.']

# 提取 sas saas
key = 'saas and sas and saaas'
res =re.findall('sa{1,2}s',key)
print(res) # ['saas', 'sas']


# 提取i开头的行
'''
re.S 基于单行
re.M 基于多行
'''
key = '''fall in love with you
i love you very much
i love she
i love her'''
res = re.findall('^i.*',key,re.M)
print(res)
# ['i love you very much', 'i love she', 'i love her']

# 匹配所有全部行
key = '''<div>静夜思
窗前明月光
疑是地上霜
举头望明月
低头思故乡
</div>'''

'''
此时key是多行
但是匹配的时候想要当作一行处理
'''
res = re.findall('<div>.*</div>',key,re.S)
print(res)
# ['<div>静夜思\n窗前明月光\n疑是地上霜\n举头望明月\n低头思故乡\n</div>']

需求:用正则对糗百的(糗图)图片数据进行解析和下载

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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#!/usr/bin/env python
#-*- encoding:utf-8 -*-

import requests
import re
import os
#1指定url
url = 'https://www.qiushibaike.com/pic/'

#自定义请求头信息
headers={
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36',
}

#2发请求
response = requests.get(url=url,headers=headers)

#3获取页面数据
page_text = response.text

#4数据解析
'''
<div class="thumb">
<a href="/article/121304175" target="_blank">
<img src="//pic.qiushibaike.com/system/pictures/12130/121304175/medium/7RG0RFB30I0KWFMI.jpg" alt="要把下面烫卷">
</a>
</div>
'''
# 该列表中存储的就是当前页面源码中所有图片的url
img_arr = re.findall('<div class="thumb">.*?<img src="(.*?)".*?>.*?</div>',page_text,re.S)

# 创建存储图片数据的文件夹
if not os.path.exists('./imgs'):
os.mkdir('imgs')
'''
# 发现是不含协议部分的
['//pic.qiushibaike.com/system/pictures/12130/121304185/medium/6X8SQWYH0BBUO1KV.jpg',....]'''
# 添加上协议
for url in img_arr:
img_url = 'https:' + url
# 持久化存储:存储的是图片的数据而不是url
# 获取图片二进制数据值
img_data = requests.get(url=img_url,headers=headers).content

# 将 6X8SQWYH0BBUO1KV.jpg 当做图片的名字
img_name = url.split('/')[-1]
img_path = 'imgs/' + img_name
with open(img_path,'wb') as f:
f.write(img_data)
print(img_name+'写入成功')