需求来源将如下字符串中pid对应的值,组织成列表形式:
getMerchandiseIds({“code”:1,“msg”:“success”,“tid”:"-6007374682839992451",“data”:{“keepTime”:180,“total”:2042,“totalTxt”:“2042”,“batchSize”:120,“pageSize”:30,“isLast”:0,“showBsFilter”:1,“showRank”:0,“headInfo”:{“isShowLabel”:1,“listStyle”:“1”,“spellCheck”:{“type”:“1”,“originWord”:“口红”}},“products”:[{“pid”:“6918464699139588940”,“isReco”:“0”},{“pid”:“6918383816403572620”,“isReco”:“0”},{“pid”:“6918976367090246728”,“isReco”:“0”},{“pid”:“6918063477853790749”,“isReco”:“0”},{“pid”:“6919173835742442889”,“isReco”:“0”}],“sortTips”:“根据大部分用户喜爱的商品,为您挑选:”}})
上边的字符串是爬虫得到的结果。
有2种解析方法:
- 返回response.text字符串getMerchandiseIds() 可以用正则提取括号里面的数据,字符串转json数据,导入一个json模块,json.loads(字符串)
- 直接使用正则匹配提取 ‘pid’: ‘(\d+)’
1. 正则提取getMerchandiseIds() 中的json字符串
str1 = 'getMerchandiseIds({"code":1,"msg":"success","tid":"-6007374682839992451","data":{"keepTime":180,"total":2042,"totalTxt":"2042","batchSize":120,"pageSize":30,"isLast":0,"showBsFilter":1,"showRank":0,"headInfo":{"isShowLabel":1,"listStyle":"1","spellCheck":{"type":"1","originWord":"口红"}},"products":[{"pid":"6918464699139588940","isReco":"0"},{"pid":"6918383816403572620","isReco":"0"},{"pid":"6918976367090246728","isReco":"0"},{"pid":"6918063477853790749","isReco":"0"},{"pid":"6919173835742442889","isReco":"0"}],"sortTips":"根据大部分用户喜爱的商品,为您挑选:"}})'
p1 = re.compile(r'[(](.*?)[)]',re.S)
result = re.findall(p1,str1)[0]
print(result)
运行结果:
{“code”:1,“msg”:“success”,“tid”:"-6007374682839992451",“data”:{“keepTime”:180,“total”:2042,“totalTxt”:“2042”,“batchSize”:120,“pageSize”:30,“isLast”:0,“showBsFilter”:1,“showRank”:0,“headInfo”:{“isShowLabel”:1,“listStyle”:“1”,“spellCheck”:{“type”:“1”,“originWord”:“口红”}},“products”:[{“pid”:“6918464699139588940”,“isReco”:“0”},{“pid”:“6918383816403572620”,“isReco”:“0”},{“pid”:“6918976367090246728”,“isReco”:“0”},{“pid”:“6918063477853790749”,“isReco”:“0”},{“pid”:“6919173835742442889”,“isReco”:“0”}],“sortTips”:“根据大部分用户喜爱的商品,为您挑选:”}}
至此json字符串就提取出来了,紧接着如下代码即可满足需求了。
products = json.loads(result)['data']['products']
lis = []
for index in products:
pid = index['pid']
lis.append(pid)
print(lis)
运行结果:
[‘6918464699139588940’, ‘6918383816403572620’, ‘6918976367090246728’, ‘6918063477853790749’, ‘6919173835742442889’]
1.1 贪婪模式
加了?是最小匹配,不加是贪婪匹配
1.2 最小匹配
加了?是最小匹配,不加是贪婪匹配
1.3 两种模式代码比较
string = 'i(love)python)'
p1 = re.compile(r'[(](.*?)[)]', re.S)
p2 = re.compile(r'[(](.*)[)]', re.S)
print(re.findall(p1, string))
print(re.findall(p2, string))
运行结果:
[‘love’]
[‘love)python’]
1.4 使用的注意点
-
正则匹配串前加了r就是为了使得里面的特殊符号不用写反斜杠了。
-
[ ]具有去特殊符号的作用,也就是说[(]里的(只是平凡的括号。
-
.是为了表示除了换行符的任一字符。*克林闭包,出现0次或无限次。
-
正则匹配串里的()是为了提取整个正则串中符合括号里的正则的内容。
-
加了?是最小匹配,不加是贪婪匹配。
-
re.S是为了让.表示除了换行符的任一字符。
2. 正则提取’pid’: ‘(\d+)’
# 字典的提取方式
print(re.findall('pid":"(\d+)', str1))
运行结果:
[‘6918464699139588940’, ‘6918383816403572620’, ‘6918976367090246728’, ‘6918063477853790749’, ‘6919173835742442889’]
显然是第二种方法提取比较简单,就一句代码就可以完成需求了。
3.提取数字
思路分析:
“”"
既然是提取数字,那么数字的形式一般是:整数,小数,整数加小数;
所以一般是形如:----.-----;
根据上述正则表达式的含义,可写出如下的表达式:"\d+.?\d*";
\d+匹配1次或者多次数字,注意这里不要写成*,因为即便是小数,小数点之前也得有一个数字;.?这个是匹配小数点的,可能有,也可能没有;\d*这个是匹配小数点之后的数字的,所以是0个或者多个;
“”"
3.1 提取指定字符对应的值
- 方法1: 提取 calibration=0.9863265752792358
str3 = 'loss=0.20478513836860657 norm_loss=0.767241849151384 roc=0.8262403011322021 pr=0.39401692152023315 calibration=0.9863265752792358 rate=0.0'
# 匹配“calibration=”后面的数字
pattern = re.compile(r'(?<=calibration=)\d+\.?\d*')
print(pattern.findall(str3))
运行结果:
[‘0.9863265752792358’]
- 方法2: 提取 calibration=0.9863265752792358
这个方法和正则提取’pid’: ‘(\d+)’使用同一种提取方式。
# 使用类型字典的方式
print(re.findall('calibration=(\d+\.?\d*)', str3))
运行结果:
[‘0.9863265752792358’]
3.2 匹配数字
# 中文逗号
str4 = "A1.45,b5,6.45,8.82"
print(re.findall(r"\d+\.?\d*", str4))
# 英文逗号
str5 = "A1.45,b5,6.45,8.82"
print(re.findall(r"\d+\.?\d*", str5))
运行结果:
[‘1.45’, ‘5’, ‘6.45’, ‘8.82’]
[‘1.45’, ‘5’, ‘6.45’, ‘8.82’]
4.匹配包含指定字符串开头的数字
# 提取包含loss开头的数字
pattern = re.compile(r'(?:loss=)\d+\.?\d*')
print(pattern.findall(str3))
运行结果:
[‘loss=0.20478513836860657’, ‘loss=0.767241849151384’]
5.匹配时间15:28:39
string = "today time is: 20210329 15:28:39 Initialize training"
pattern = re.compile(r'\d{2}:\d{2}:\d{2}')
print(pattern.findall(string))
运行结果:
[‘15:28:39’]
6.匹配时间,2021-03-29 15:28:39
string = "today time is: 2021-03-29 15:28:39 Initialize training"
pattern = re.compile(r'\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}')
print(pattern.findall(string))
运行结果:
[‘2021-03-29 15:28:39’]
7.结语
上边的栗子是自己学习过程中,遇到的问题,自己总结了一下,说不定哪天会再次碰到类似的需求呢。