前言
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模組提供了四個功能:dumps
、loads
、dump
、load
,用於字串和python資料型別之間進行轉換。
json.dumps()
:將 Python 物件解碼轉換成 JSON 字串json.loads()
:把JSON 格式字串解碼轉換成Python 物件json.dump()
:將Python內建型別序列化為JSON 物件後寫入檔案json.load()
:讀取檔案中JSON 形式的字串元素轉化成Python 型別
其中類檔案物件的理解,其實就是具有read()或者write()方法的物件,比如f = open("test.txt","r")
f就是類檔案物件。下面對dumps
和loads
分別舉例說明:
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物件的一個過程,常用的兩個函式是dumps
和dump
函式。兩個函式的唯一區別就是dump
把python物件轉換成json物件生成一個fp的檔案流,而dumps
則是生成了一個字串。
解碼中常用的引數:
Skipkeys
:預設值是False,如果dict的keys內的資料不是python的基本型別(str,unicode,int,long,float,bool,None),設定為False時,就會報TypeError的錯誤。此時設定成True,則會跳過這類keyensure_ascii
:預設值True,如果dict內含有non-ASCII的字元,則會類似\uXXXX的顯示資料,設定成False後,就能正常顯示indent
:應該是一個非負的整型,如果是0,或者為空,則一行顯示資料,否則會換行且按照indent的數量顯示前面的空白,這樣列印出來的json資料也叫pretty-printed jsonseparators
:分隔符,實際上是(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
會變成null
,True
和False
轉換後首字母都會變成小寫噢!他們的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資料格式化後的層級顯示如下: