数据提取的方式:
1、json包
2、jsonpath表达式
3、正则表达式
使用场景:
1、下一个接口的请求参数需要用到上一个接口响应结果的某些字段与取值
2、下一个接口url需要用到上一个接口响应结果的某些字段与取值
3、需要响应结果的某些字段与取值做断言
4、......
一、json包
json.dumps() :将字典类型转换为str类型
json.loads(): 将str类型转换为字典类型
import json
#json.dumps()
test_data = {
"key1": "value1",
"key2": "value2",
"key3": "value3",
}
print("test_data的类型:", type(test_data))
test_data_2 = json.dumps(test_data)
print(test_data_2, type(test_data_2))
# 运行结果
test_data的类型: <class 'dict'>
{"key1": "value1", "key2": "value2", "key3": "value3"} <class 'str'>
import json
# json.loads()
test_str = '{"key1": "value1","key2": "value2","key3": "value3"}'
print("test_data的类型:", type(test_str))
test_data = json.loads(test_str)
print(test_data, type(test_data))
# 运行结果
test_data的类型: <class 'str'>
{'key1': 'value1', 'key2': 'value2', 'key3': 'value3'} <class 'dict'>
二、jsonpath表达式(只能处理接口响应结果为json格式的数据)
# 特殊字符含义
$: 根元素
. 与[]: 子元素
..: 递归搜索
*: 通配
[]: 子元素操作符,索引取值,切片,字段名称取值(多个字段用逗号隔开)
?(): 过滤表达式
from jsonpath import jsonpath
import pprint
teacher_info = {"class":
{"class_1": [
{"name": "张三",
"sex": "男",
"age": 30,
"height": 175,
"info": "语文"
},
{"name": "张四",
"sex": "男",
"age": 28,
"height": 185,
"info": "数学"
},
{"name": "小王",
"sex": "女",
"age": 18,
"height": 170,
"info": "英语"
},
{"name": "张五",
"sex": "男",
"age": 28,
"height": 185,
"info": "物理"
},
{"name": "张六",
"sex": "男",
"age": 28,
"height": 190,
"info": "化学"
}
],
"class_2": {
"name": "李四",
"sex": "男",
"age": 30,
"height": 185.5,
"info": "生物"
}
}
}
根元素下面的子元素
res1 = jsonpath(teacher_info, "$.class")
pprint.pprint(res1)
res2 = jsonpath(teacher_info, "$[class]")
pprint.pprint(res2)
.与[]混合使用
res3 = jsonpath(teacher_info, "$[class].class_1")
pprint.pprint(res3)
递归查找
res4 = jsonpath(teacher_info, "$..name")
pprint.pprint(res4)
*通配符
res5 = jsonpath(teacher_info, "$.class.class_1.*")
pprint.pprint(res5)
按索引取值
res6 = jsonpath(teacher_info, "$..class_1[0,1]")
pprint.pprint(res6)
切片,取值左闭右开
res7 = jsonpath(teacher_info, "$..class_1[0:1]")
print(res7)
获取指定字段
res8 = jsonpath(teacher_info, "$..class_1.[name,sex,age]")
print(res8)
单个条件匹配
res9 = jsonpath(teacher_info, "$..class_1.[?(@.age<=35)]")
pprint.pprint(res9)
多个条件匹配,与运算:&& 或 and
res10 = jsonpath(teacher_info, "$..class_1.[?(@.sex=='女' && @.age==18)]")
pprint.pprint(res10)
多条件匹配,或运算:|| 或 or
res11 = jsonpath(teacher_info, "$..class_1.?(@.sex=='男' || @.age <= 35)")
pprint.pprint(res11)
成员运算
res12 = jsonpath(teacher_info, "$..class_1.[?(@.age in [28,30])].[name,age]")
print(res12)
三、正则表达式
# 单字符匹配
. 匹配.前面的一个字符,该字符后面任意一个字符
[] 匹配[]中的任意一个字符,并不是一个整体,返回list,按查找对象里的顺序输出
\d 匹配数字,返回list
\D 匹配非数字
\s 匹配空白,空格,tab键
\S 匹配非空白
\w(小写) 匹配非特殊字符 属于非特殊字符:a-z,A-Z,0-9,_,汉字
\W(大写) 匹配特殊字符 属于特殊字符:非字母、非数字、非汉字、非下划线
# 多字符匹配
* 匹配前一个字符出现0次或者无限次 【贪婪模式],未匹配到即说明出现0次
+: 匹配前一个字符出现1次或者无限次,即至少有1次匹配一个字符串,只返回出现1次或者无限次的 【贪婪模式】
? 匹配前一个字符出现0次或者1次,要么有1次,要么没有 【非贪婪模式】
{n} 匹配前一个字符连续出现n次
{n,m} 匹配前一个字符出现n次到m次
# 逻辑运算
| 或运算
# 边界值
^:匹配以后一个字符开头的
$:匹配结尾处
import re
# 正则表达式
# 单字符匹配
# . 匹配.前面的一个字符,该字符后面任意一个字符
test_str1 = 'python'
res1 = re.findall("p.", test_str1)
print(res1)
# [] 匹配[]中的任意一个字符,并不是一个整体,返回list,按查找对象里的顺序输出
test_str2 = 'python'
res2 = re.findall("[phy]", test_str2)
print(res2)
# \d 匹配数字,返回list
test_str3 = 'python123'
res3 = re.findall("\d", test_str3)
print(res3)
# \D 匹配非数字
test_str4 = 'python123'
res4 = re.findall("\D", test_str4)
print(res4)
# \s 匹配空白,空格,tab键
test_str5 = 'pyt hon1 23'
res5 = re.findall("\s", test_str5)
print(res5)
# \S 匹配非空白
test_str6 = 'pyt hon1 23'
res6 = re.findall("\S", test_str6)
print(res6)
# \w(小写) 匹配非特殊字符 属于非特殊字符:a-z,A-Z,0-9,_,汉字
test_str7 = 'hfdur#$%^^&fhus'
res7 = re.findall('\w', test_str7)
print(res7)
# \W(大写) 匹配特殊字符 属于特殊字符:非字母、非数字、非汉字、非下划线
test_str8 = 'hfdur#$%^^&fhu_s你好你好'
res8 = re.findall('\W', test_str8)
print(res8)
# 多字符匹配,未匹配到返回空,最后一位会多匹配一次
# * 匹配前一个字符出现0次或者无限次 【贪婪模式],未匹配到即说明出现0次
test_str1 = "fhhhhhhhiruyyrjhf"
res1 = re.findall('h*', test_str1)
print(res1)
# +: 匹配前一个字符出现1次或者无限次,即至少有1次匹配一个字符串,只返回出现1次或者无限次的 【贪婪模式】
test_str2 = "fhhhhhhhiruuuuyyrjhf"
res2 = re.findall('fh+', test_str2)
print(res2)
# 匹配前一个字符出现0次或者1次,要么有1次,要么没有 【非贪婪模式】
test_str3 = "fhhhhhhhiruuyyrujhf"
res3 = re.findall('ru?', test_str3)
print(res3)
# {n} 匹配前一个字符连续出现n次
test_str4 = "fhhhhhhhiruuyyrujhf"
res4 = re.findall('ru{2}', test_str3)
print(res4)
# {n,m} 匹配前一个字符出现n次到m次
test_str5 = "fhhhhhhhiruuyyrujhf"
res5 = re.findall('ru{1,2}', test_str5)
print(res5)
# | 或运算
test_str1 = "fhhhhhhhiruuyyrujhf"
res1 = re.findall('fh|ru|yy', test_str1)
print(res1)
# 边界值
# ^:匹配以后一个字符开头的
test_str = "hello python"
res = re.findall("^he", test_str)
print(res)
# $:匹配结尾处
test_str = "hello python"
res = re.findall("on$", test_str)print(res)
# 分组匹配
# 要去接口响应结果里面提取的参数的key
test_demo = '{"#key1#":"val1","#key2#":"val2"}'
# res = re.findall("#(\w.+?)#",test_demo)
res = re.findall("#(\w.+?)#", test_demo)
print(res)