天天看點

json_extract提取複雜json_一篇長文帶你在python裡玩轉Json資料!

json_extract提取複雜json_一篇長文帶你在python裡玩轉Json資料!

Json簡介

Json(JavaScript Object Notation)

很多網站都會用到Json格式來進行資料的傳輸和交換。

json_extract提取複雜json_一篇長文帶你在python裡玩轉Json資料!

這因為Json是一種輕量級的資料交換格式,具有資料格式簡單,讀寫友善易懂等很多優點。用它來進行前後端的資料傳輸,大大的簡化了伺服器和用戶端的開發工作量。

而且相對于XML來說,更加的輕量級,更友善解析。

今天我們講講如何在python裡玩轉Json資料?

json_extract提取複雜json_一篇長文帶你在python裡玩轉Json資料!

在Json中,遵循“key-value”的這樣一種方式。

比如最簡單的這種:“{"name" : "zhuxiao5"}”,跟python 裡的字典似的,也是一個Json格式的資料。

複雜一點的比如這種(後文會多次使用到這個例子):

{
    "animals": {
        "dog": [
            {
                "name": "Rufus",
                "age":15
            },
            {
                "name": "Marty",
                "age": null
            }
        ]
    }
}
           

以上圖為例,再多說幾句Json格式的特點

  • 對象通過鍵值對表現;
  • 鍵通過雙引号包裹,後面跟冒号“:”,然後跟該鍵的值;
  • 值可以是字元串、數字、數組等資料類型;
  • 對象與對象之間用逗号隔開;
  • “{}”用來表達對象;
  • “[]”用來表達數組;

Python中的Json子產品

Python中也自帶了Json子產品,其中json.dumps()、json.loads()較為常用。

json.dumps() 是将 python 對象轉化為 json。

json.loads() 是将 json 轉化為 python 對象。

json_extract提取複雜json_一篇長文帶你在python裡玩轉Json資料!
#json.dumps(),json.loads()
import json
dict_data = {"a": 1, "b": 2}
# 将dict格式資料轉換成json格式字元串
dump_data = json.dumps(dict_data)
# 将json格式字元串轉換成對應的python值
load_data = json.loads(dump_data)
# 列印轉換結果
print(type(dict_data),dict_data)
print(type(dump_data),dump_data)
print(type(load_data),load_data)
           

運作結果:

<class 'dict'> {'a': 1, 'b': 2}
<class 'str'>   {"a": 1, "b": 2}
<class 'dict'> {'a': 1, 'b': 2}
           

在例子中一開始的變量 dict_data 是一個字典,json.dumps() 後,将dict格式資料轉換成json格式字元串。這時候雖然都是{'a': 1, 'b': 2},但是格式卻前後不一樣。随後又通過 json.loads(),重新将json格式字元串轉換成字典。

線上解析Json

在實際應用中,要 提取json資料,就要了解傳回json資料的結構。

可是Json格式的資料往往是這樣的。

json_extract提取複雜json_一篇長文帶你在python裡玩轉Json資料!
json_extract提取複雜json_一篇長文帶你在python裡玩轉Json資料!

大家别擔心,我們可以将資料複制到一些json插件或線上解析!

比如這個插件是小五常用的:

json_extract提取複雜json_一篇長文帶你在python裡玩轉Json資料!

此時再打開剛才的網址

json_extract提取複雜json_一篇長文帶你在python裡玩轉Json資料!

是不是清晰了很多呢?

如果用python來擷取裡面的資料怎麼做的?

先利用 json.loads() 來将 Json 轉成字典,再用 get() 函數直到得到我們想要的list 對象,那麼對于 list 裡面的資料我們用個 for 循環就行啦~

額,有點繞。

json_extract提取複雜json_一篇長文帶你在python裡玩轉Json資料!

還是文章一開始的例子,我們想擷取其中所有狗狗的名字:

{
    "animals": {
        "dog": [
            {
                "name": "Rufus",
                "age":15
            },
            {
                "name": "Marty",
                "age": null
            }
        ]
    }
}
           

我們可以這樣做:

load_data = json.loads(dump_data)
data = load_data.get("animals").get("dog")
result1 = []
for i in data:
    result1.append(i.get("name"))
print(result1)
           

運作結果:

['Rufus', 'Marty']
           

這樣确實可以獲得我們想要的結果。

PS:類似的線上解析網站也有很多,比如 https://www.json.cn 。

JsonPath

不知道大家還記不記得,在一開始介紹Json時,我提到了它相對于XML來說,更加的輕量級,更友善解析。

既然 XML 人家都有 XPATH ,那麼Json有沒有類似的工具呢?

json_extract提取複雜json_一篇長文帶你在python裡玩轉Json資料!

JsonPath 是一種資訊抽取類庫,是從Json文檔中抽取指定資訊的工具。

JsonPath 對于 Json 來說, 相當于 XPATH 對于 XML。

Json結構清晰,可讀性高,複雜度低,非常容易比對,下表是JsonPath的用法。

json_extract提取複雜json_一篇長文帶你在python裡玩轉Json資料!
json_extract提取複雜json_一篇長文帶你在python裡玩轉Json資料!

沒錯,還是這個例子,我們這次嘗試用 JsonPath 擷取其中所有狗狗的名字:

{
    "animals": {
        "dog": [
            {
                "name": "Rufus",
                "age":15
            },
            {
                "name": "Marty",
                "age": null
            }
        ]
    }
}
           

我們可以這樣做:

load_data = json.loads(dump_data)
jobs=load_data['animals']['dog']
result2 = []
for i in data:
# 從根節點開始,比對name節點
    result2.append(jsonpath.jsonpath(i,'$..name')[0])
print(result2)
           

其中 $..name 代表從根節點開始,比對name節點

運作結果:

['Rufus', 'Marty']
           

利用 JsonPath 同樣可以獲得我們想要的結果。

我們在後續執行個體演練中将繼續采用 JsonPath 來抽取資料。

執行個體演練

示例:我們利用

網易雲音樂評論API

來生成Json資料,并從中擷取熱評資料。

http://music.163.com/api/v1/resource/comments/R_SO_4_483671599?limit=10&offset=0
           

在浏覽器(已安裝Json解析插件)中打開:

json_extract提取複雜json_一篇長文帶你在python裡玩轉Json資料!
json_extract提取複雜json_一篇長文帶你在python裡玩轉Json資料!

标紅區域的資料是我們本次想要擷取的。

json_extract提取複雜json_一篇長文帶你在python裡玩轉Json資料!
def get_comments(url):
    data = []
    doc = get_json(url)
    jobs=doc['hotComments']
    for job in jobs:
        dic = {}
        #從根節點開始,比對content節點
        dic['content']=jsonpath.jsonpath(job,'$..content')[0] #評論
        dic['time']= stampToTime(jsonpath.jsonpath(job,'$..time')[0]) #時間
        dic['userId']=jsonpath.jsonpath(job['user'],'$..userId')[0]  #使用者ID
        dic['nickname']=jsonpath.jsonpath(job['user'],'$..nickname')[0]#使用者名
        dic['likedCount']=jsonpath.jsonpath(job,'$..likedCount')[0] #贊數
        data.append(dic)
    return pd.DataFrame(data)

final_result = get_comments('http://music.163.com/api/v1/resource/comments/R_SO_4_483671599?limit=10&offset=0')
           

(完整代碼見文末下載下傳位址)

運作結果:

json_extract提取複雜json_一篇長文帶你在python裡玩轉Json資料!

成功擷取√

希望本文能讓大家以後玩轉Json資料更輕松~

json_extract提取複雜json_一篇長文帶你在python裡玩轉Json資料!