【python介面自動化】- 使用json及jsonpath轉換和提取資料

miki_peng發表於2020-12-11

前言

JSON(JavaScript Object Notation)是一種輕量級的資料交換格式。它可以讓人們很容易的進行閱讀和編寫,同時也方便了機器進行解析和生成,適用於進行資料互動的場景,比如網站前臺與後臺之間的資料互動。簡單說就是javascript中的物件和陣列,通過這兩種結構可以表示各種複雜的結構。

​ ?物件:物件在js中是花括號{}括起來的內容,資料結構為{key:value,key:value,...}這樣的鍵值對結構,在物件導向的語言中,key為物件的屬性,value為對應的屬性值,所以很容易理解,取值方法為物件.key來獲取屬性值,這個屬性值的型別可以是數字、字串、陣列、物件這幾種。

​ ?陣列:陣列在js中是中括號[]括起來的內容,資料結構為["Python", "javascript", "C++",..],類似python中的列表,取值方式和所有語言中一樣,使用索引獲取,欄位值的型別可以是數字、字串、陣列、物件幾種。

json模組

​ 在之前的request庫介紹中就提到過,現在99%的介面返回的資料都是json格式,在python中,有專門處理json格式的模組——json模組,在python2.6之後的版本都自帶了這一個模組,直接匯入import json即可。json模組提供了四個功能:dumpsloadsdumpload,用於字串和python資料型別之間進行轉換。

  • json.dumps():將 Python 物件解碼轉換成 JSON 字串
  • json.loads():把JSON 格式字串解碼轉換成Python 物件
  • json.dump():將Python內建型別序列化為JSON 物件後寫入檔案
  • json.load():讀取檔案中JSON 形式的字串元素轉化成Python 型別
image-20201211171351461

​ 其中類檔案物件的理解,其實就是具有read()或者write()方法的物件,比如f = open("test.txt","r") f就是類檔案物件。下面對dumpsloads分別舉例說明:

import json

data = [{'a': 1, 'b': 2, 'c': 3}]
data2 = json.dumps(data)  # 將python物件轉換成json字串
print(data2)
print(type(data2))
print("-------還可以使用引數格式化輸出json格式--------")
print(json.dumps(data, sort_keys=True, indent=4, separators=(',', ': ')))

jsonData = '{"a":1,"b":2,"c":3,"d":4,"e":5}'
text = json.loads(jsonData)
print("---------json轉python---------")
print(text)
print(type(jsonData))

# 返回結果如下:
# C:\software\python\python.exe D:/learn/test.py
# [{"a": 1, "b": 2, "c": 3}]
# <class 'str'>
# -------還可以使用引數格式化輸出json格式--------
# [
#     {
#         "a": 1,
#         "b": 2,
#         "c": 3
#     }
# ]
# ---------json轉python---------
# {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
# <class 'str'>
# 
# Process finished with exit code 0

dumps解碼的過程,是把python物件轉換成json物件的一個過程,常用的兩個函式是dumpsdump函式。兩個函式的唯一區別就是dump把python物件轉換成json物件生成一個fp的檔案流,而dumps則是生成了一個字串。

解碼中常用的引數

  • Skipkeys:預設值是False,如果dict的keys內的資料不是python的基本型別(str,unicode,int,long,float,bool,None),設定為False時,就會報TypeError的錯誤。此時設定成True,則會跳過這類key
  • ensure_ascii:預設值True,如果dict內含有non-ASCII的字元,則會類似\uXXXX的顯示資料,設定成False後,就能正常顯示
  • indent:應該是一個非負的整型,如果是0,或者為空,則一行顯示資料,否則會換行且按照indent的數量顯示前面的空白,這樣列印出來的json資料也叫pretty-printed json
  • separators:分隔符,實際上是(item_separator, dict_separator)的一個元組,預設的就是(',','?;這表示dictionary內keys之間用“,”隔開,而KEY和value之間用“:”隔開
  • encoding:預設是UTF-8,設定json資料的編碼方式
  • sort_keys:將資料根據keys的值進行排序。

​ python 型別向 json 型別的轉化對照表如下:

Python JSON
dict object(物件)
list, tuple array(陣列)
str, unicode string
int, long, float number
True true
False false
None null

​ 反之,json 型別轉換到 python 的型別對照表:

JSON Python
object(物件) dict
array(陣列) list
string unicode
number (int) int, long
number (real) float
true True
false False
null None

​ ?特別注意:轉換的時候,python的None會變成nullTrueFalse轉換後首字母都會變成小寫噢!他們的json格式在python中是無法被識別的,會被當成變數處理。

​ 更多的相關內容,可以查閱python的官方文件:https://docs.python.org/2/library/json.html

jsonpath庫

​ JsonPath是一種資訊抽取類庫,是從JSON文件中抽取指定資訊的工具,提供多種語言實現版本,包括JavaScript、Python、PHP和Java。JsonPath對於JSON來說,就相當於XPATH對於XML。JsonPath結構清晰,可讀性高,複雜度低,非常容易匹配,下表中對應了XPath的用法。

Xpath JSONPath 描述
/ $ 根節點
. @ 現行節點
/ . or [] 取子節點
.. n/a 取父節點,Jsonpath未支援
// .. 不管位置,選擇所有符合條件的節點
* * 匹配所有元素節點
@ n/a 根據屬性訪問,JsonPath不支援
[] [] 迭代器(可以在裡邊做簡單的迭代操作,如陣列下標,根據內容選值等)
| [,] 支援迭代器中做多選
[] ?() 支援過濾操作
n/a () 支援表示式計算
() n/a 分組,JsonPath不支援
  • pip安裝pip install jsonpath,官網文件:http://goessner.net/articles/JsonPath
  • 使用方法jsonpath.jsonpath(),結果會以列表形式返回,如下請求介面返回資料提取例子
    • ?引數1:資料物件
    • ?引數2:jsonpath表示式
import requests
import jsonpath

login_url = "http://localhost:8080/member/login"
login_data = {
    "mobile_phone": "15867554893",
    "pwd": "123456qwe",
}
header = {    "Content-Type": "application/json"}
# 傳送登入的請求
response = requests.post(url=login_url, json=login_data, headers=header)
# 獲取返回的json資料
json_data = response.json()


member_id = jsonpath.jsonpath(json_data, "$..id")[0]
type_token = jsonpath.jsonpath(json_data, "$..token_type")[0]
token = jsonpath.jsonpath(json_data, "$..token")[0]
print(json_data)
print("會員id:{}".format(member_id))
print("token的型別:{}".format(type_token))
print("token:{}".format(token))

​ 執行返回的資料如下:

C:\software\python\python.exe D:/learn/test.py
{'code': 0, 'msg': 'OK', 'data': {'id': 59514, 'money': 34000.0, 'mobile_phone': '15612345678', 'reg_name': 'miki測試', 'reg_time': '2020-11-16 22:18:59.0', 'type': 0, 'token_info': {'token_type': 'Bearer', 'expires_in': '2020-12-10 00:30:01', 'token': 'eyJhbGciOiJIUzUxMiJ9.eyJtZW1iZXJfaWQiOjU5NTE0LCJleHAiOjE2MDc1MzE0MDF9.GAoCY5RZ_FWUIRMNXdURdH5y7zKuETo1qsq9Z9No9AaWvo2QGLR9maWxEY31Ddy6a7QmpT56xKg7N3YwGLTbOQ'}}}
會員id:59514
token的型別:Bearer
token:eyJhbGciOiJIUzUxMiJ9.eyJtZW1iZXJfaWQiOjU5NTE0LCJleHAiOjE2MDc1MzE0MDF9.GAoCY5RZ_FWUIRMNXdURdH5y7zKuETo1qsq9Z9No9AaWvo2QGLR9maWxEY31Ddy6a7QmpT56xKg7N3YwGLTbOQ

​ 登入介面返回的json資料格式化後的層級顯示如下:

【python介面自動化】- 使用json及jsonpath轉換和提取資料

相關文章