本地案例测试数据,从 goessner - JsonPath 中拷贝的
{
"store": {
"book": [
{ "category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{ "category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
},
{ "category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99
},
{ "category": "fiction",
"author": "J. R. R. Tolkien",
"title": "The Lord of the Rings",
"isbn": "0-395-19395-8",
"price": 22.99
}
],
"bicycle": {
"color": "red",
"price": 19.95
}
}
}
本地案例
# 导入 json
import json
# 导入 jsonpath
import jsonpath
# 1、json 读取本地文件
obj = json.load(open('test.json', 'r', encoding='utf-8'))
# 2、jsonpath 进行分析查找
# 获取所有书籍的作者名称
list = jsonpath.jsonpath(obj, '$.store.book[*].author') # ['Nigel Rees', 'Evelyn Waugh', 'Herman Melville', 'J. R. R. Tolkien']
list = jsonpath.jsonpath(obj, '$..author') # ['Nigel Rees', 'Evelyn Waugh', 'Herman Melville', 'J. R. R. Tolkien']
# 获取 store 下面的所有元素
list = jsonpath.jsonpath(obj, '$.store.*') # [[{'category': 'reference', 'author': 'Nigel Rees', 'title': 'Sayings of the Century', 'price': 8.95}, ...], {'color': 'red', 'price': 19.95}]
# 获取第 3 本书
list = jsonpath.jsonpath(obj, '$..book[2]') # [{'category': 'fiction', 'author': 'Herman Melville', 'title': 'Moby Dick', 'isbn': '0-553-21311-3', 'price': 8.99}]
# 获取最后一本书
list = jsonpath.jsonpath(obj, '$..book[(@.length - 1)]') # [{'category': 'fiction', 'author': 'J. R. R. Tolkien', 'title': 'The Lord of the Rings', 'isbn': '0-395-19395-8', 'price': 22.99}]
# 获取前 2 本书
list = jsonpath.jsonpath(obj, '$..book[0, 1]') # 错误写法,[0, 1]不能有空格,不然只会生效第一个值,后面的值不生效
list = jsonpath.jsonpath(obj, '$..book[0,1]') # [{'category': 'reference', 'author': 'Nigel Rees', 'title': 'Sayings of the Century', 'price': 8.95}, {'category': 'fiction', 'author': 'Evelyn Waugh', 'title': 'Sword of Honour', 'price': 12.99}]
list = jsonpath.jsonpath(obj, '$..book[:2]') # 切片写法,结果一样
# 条件过滤需要再 () 前面添加一个 ?
# 过滤出包含 isbn 的书
list = jsonpath.jsonpath(obj, '$..book[?(@.isbn)]') # [{'category': 'fiction', 'author': 'Herman Melville', 'title': 'Moby Dick', 'isbn': '0-553-21311-3', 'price': 8.99}, {'category': 'fiction', 'author': 'J. R. R. Tolkien', 'title': 'The Lord of the Rings', 'isbn': '0-395-19395-8', 'price': 22.99}]
# 查询哪本书超过 10 块钱
list = jsonpath.jsonpath(obj, '$..book[?(@.price > 10)]') # [{'category': 'fiction', 'author': 'Evelyn Waugh', 'title': 'Sword of Honour', 'price': 12.99}, {'category': 'fiction', 'author': 'J. R. R. Tolkien', 'title': 'The Lord of the Rings', 'isbn': '0-395-19395-8', 'price': 22.99}]
# 输出
print(list)
远程案例
# 测试某站的城市地址接口
# 使用 urllib
import urllib.request
# 使用 json
import json
import jsonpath
# 获取地址
url = 'https://dianying.taobao.com/cityAction.json?activityId&_ksTS=1668502740745_108&jsoncallback=jsonp109&action=cityAction&n_s=new&event_submit_doGetAllRegion=true'
# 请求头
headers = {
# 带冒号的请求头都需要注释掉,报错:ValueError: Invalid header name b':Authority'
# ':authority': 'dianying.taobao.com',
# ':method': 'GET',
# ':path': '/cityAction.json?activityId&_ksTS=1668502740745_108&jsoncallback=jsonp109&action=cityAction&n_s=new&event_submit_doGetAllRegion=true',
# ':scheme': 'https',
# 'accept': 'text/javascript, application/javascript, application/ecmascript, application/x-ecmascript, */*; q=0.01',
# 报错:UnicodeDecodeError: 'utf-8' codec can't decode byte 0x8b in position 1: invalid start byte
# 'accept-encoding': 'gzip, deflate, br',
'accept-language': 'zh-CN,zh;q=0.9',
'bx-v': '2.2.3',
'cookie': 't=1e424829769814085473c593565f4f5e; cookie2=17da1c30f22c22dd8d81dd3a871ab15b; v=0; _tb_token_=e817e63793373; cna=YQP5G0dsBVICAXToSX0EYCa1; xlly_s=1; isg=BPX1ozOY-se3Ah57r0dv0iYMBHevcqmEGFxmE3ca42y7ThVAP8MsVEZAmBL4DsE8; l=eBTcoCz7T1tElPbMBOfZnurza779LIRAguPzaNbMiOCP97CH57nFW6zmqRTMCnGVhsF9R3kzvXKpBeYBclYsjqj4axom4zHmn; tfstk=cJ1lBkVp-nisATNdcgO71aCmdIyOZYcej65fgrjQfnFphI1ViZkqQ2V7o3q_4v1..',
'referer': 'https://dianying.taobao.com/',
'sec-ch-ua': '"Google Chrome";v="107", "Chromium";v="107", "Not=A?Brand";v="24"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"macOS"',
'sec-fetch-dest': 'empty',
'sec-fetch-mode': 'cors',
'sec-fetch-site': 'same-origin',
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36',
'x-requested-with': 'XMLHttpRequest'
}
# 请求对象
request = urllib.request.Request(url=url, headers=headers)
# 模拟浏览器向服务器发起请求
response = urllib.request.urlopen(request)
# 响应数据转成字符串
content = response.read().decode('utf-8')
# 会发现拿回来的数据是一个 jsonp109({xx: xx}); 包裹的字符串,放到 https://www.json.cn/ 解析也失败
# 解决办法:删除 'jsonp109(' 与后面的 ');' 即可
# 代码切割
content = content.split('(')[1].split(')')[0]
# 字符串转 json
obj = json.loads(content)
# 将内容写入文件(使用 json.loads() 则不需要存储)
with open('test.json', 'w', encoding='utf-8') as f:
f.write(content)
# 方式一:读取文件(需要存储,在读出来)
obj = json.load(open('test.json', 'r', encoding='utf-8'))
# 方式二:字符串转 json(不需要存储,直接使用)
# obj = json.loads(content)
# 导出所有 regionName 名称
regionNames = jsonpath.jsonpath(obj, '$..regionName')
# 输出
print(regionNames)