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

前言

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的官方文檔://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,官網文檔://goessner.net/articles/JsonPath
  • 使用方法jsonpath.jsonpath(),結果會以列表形式返回,如下請求介面返回數據提取例子
    • 🍊參數1:數據對象
    • 🍎參數2:jsonpath表達式
import requests
import jsonpath

login_url = "//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數據格式化後的層級顯示如下: