2018年5月20日 星期日

Python 資料處理(1) --- Json格式

很多網站都改以 JSON 來顯示或儲存資料,但 JSON格式簡單卻常常讓人誤解搞錯,今天就以一個簡單例子做說明,Python 處理 JSON 是件簡單的事,但如果遇到不正常的 JSON 格式,在解析上就無法處理,筆者就舉例一個看似異常又感覺不出哪裡怪的 JSON 範例來做說明,讓我們繼續看下去。
以下是有問題的 JSON 資料格式:
"{blog:'iinfo', blogurl:'http://white5168.blogspot.tw/', facebook:'@aminiinfo', facebookurl:'https://www.facebook.com/aminiinfo/', topic:[{excel:'VBA Crawler', python:'Deep Learning', gas:'Google Apps Script', line:'Line Notify'}]}"
拿這 JSON 到 Json Parser Online 驗證格式是否正確。

其實聰明的讀者,一眼就看出這 JSON 異常的點在哪裡,而筆者一開始也是認為這樣的格式是正確,直到用 Python 處理遇到 JSONDecodeError 錯誤 ( JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1) ),Python 無法順利對這 JSON進行處理,這時才花時間去釐清發生原因。

問題原因其實很簡單,JSON 的 Key 與 Value 都要用雙引號標記起來( 詳見 JSON Schema 說明 ),而筆者上述所列 JSON 的 Key 與 Value,只有 Value 是單引號,這樣並不符 JSON 的格式,所以 Python 無法處理,而內容依舊是 string 型態。

在 json.loads、json.dumps 無法處理的狀態下,上網找了尋找解決方法,發現原來有不少人有遇到相同的問題,回歸到問題的根本,還是要將 Key 與 Value 加入雙引號才行。

但在 Python 中怎麼處理呢? 正規表示法 (Regular Expression)。
以下的程式碼將錯誤的 JSON 進行轉換。
import pandas as pd
import json
import re
data = "{} && {blog:'iinfo', blogurl:'http://white5168.blogspot.tw/', facebook:'@aminiinfo', facebookurl:'https://www.facebook.com/aminiinfo/', topic:[{excel:'VBA Crawler', python:'Deep Learning', gas:'Google Apps Script', line:'Line Notify'}]}"
json_data = data.split("&& ")[1]
json_data = re.sub(r"://", r"--", json_data);
json_data = re.sub(r"(,?)(\w+?)\s*?:", r"\1'\2':", json_data);
json_data = re.sub(r"--", r"://", json_data);
json_data = json_data.replace("'", "\"");
json_data

最後將 "topic" 放到 pandas 中。
jd = json.loads(json_data)
df = pd.DataFrame(jd['topic'])
df

藉由以上例子說明如何處理異常 JSON 格式,對於 JSON 異常要請各位讀者多加注意。

參考資料: