首頁 > 軟體

python-json校驗-jsonpath解析

2022-11-21 14:01:28

背景

在進行介面自動化測試的時候,對響應結果進行校驗,基本上都是對json資料的校驗,響應內容十分複雜,當然驗證也是一個很龐大的工程 ,不過都是可以通過jsonpath 解決。

JSONPath 提供了強大的 JSON 解析功能,可以更便捷靈活的用來獲取對應的 JSON 內容。

表示法

JSONPath 有兩種表示方式, 可以使用點表示法,也可以使用括號表示法

  • 點表示法 例子:$.store.book[0].title
  • 括號表示法 例子:$['store']['book'][0]['title']

官方幫助檔案

jsonpath的語法

語法描述
$根物件/元素
@當前物件/元素
. 或者 []子運運算元,匹配下級元素
..遞迴下降,遞迴方式匹配所有子元素
*萬用字元。所有物件/元素,無論其名稱
[]下標運運算元,jsonpath 從0開始
[,]連線的操作符,多個結果拼接成列表返回
[開始:結束:步驟]從 ES4 借來的陣列切片運運算元。
?()應用過濾器(指令碼)表示式。
()指令碼錶示式,使用底層指令碼引擎。

範例

{ "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
    }
  }
}
jsonpath結果備註
$.store.book[*].author所有書籍的作者
$..author所有的作者
$.store.*商店下的所有元素/物件,包括書籍和自行車
$.store..price商店裡所有元素/物件的價格
$..book[2]下標從0開始,第3本書
$..book[(@.length-1)]按順序排列最後一本書用到了()和@兩個語法
$..book[-1:]按順序排列最後一本書用到了[]陣列下標切片
$..book[0,1]第1本書和第2本書,前兩本書
$..book[:2]第1本書和第2本書,前兩本書$…book[0:2] ,從0開始,0 1,前兩本書
$..book[?(@.isbn)]有isbn欄位的所有書籍
$..book[?(@.price<10)]所有價格小於10的書籍
$..*json結構的所有元素

實戰

安裝jsonpath

pip3 install jsonpath

以網上一個開源的獲得天氣的API為例子:

def test_get_json(self):
        r = requests.get("http://t.weather.sojson.com/api/weather/city/101191102")
        print(r.text)
        r_json = r.json()
        # 用點方法來獲得notice的內容
        yesterday = jsonpath(r_json, "$.data.yesterday.notice")  
        print(yesterday)
        # 獲得aqi=15 的forecast元素
        aqi = jsonpath(r_json, "$..forecast[?(@.aqi==15)]")
        print(aqi)

當不知道有jsonpath這個神器的時候,我是通過遍歷一個個元素,然後再去比對具體的欄位資訊,比如下方:獲得duration 超過7000 的api資訊

{
	"apis": [{
		"path": "/path",
		"duration": 7890
	}, {
		"path": "/path",
		"duration": 6890
	}, {
		"path": "/path",
		"duration": 5890
	}]
}

通過遍歷的方式獲得:

apis = '{"apis":[{"path":"/path","duration":7890},{"path":"/path","duration":6890},{"path":"/path","duration":5890}]}'
print(json.loads(apis))
apis_json = json.loads(apis)
# 一個個遍歷
api_duration = []
for api in apis_json["apis"]:
   duration = api["duration"]
   if int(duration) > 7000:
       print(str(duration))
       api_duration.append(api["path"])
print(api_duration)

通過jsonpath獲得

#jsonpath 更簡單
api_duration2 = jsonpath(apis_json, "$.apis[?(@.duration>7000)].path")
print(api_duration2)

以上為個人經驗,希望能給大家一個參考,也希望大家多多支援it145.com。


IT145.com E-mail:sddin#qq.com