공부하자

반정형 데이터 - JSON

|

빅데이터 청년인재 Day 8


목차


JSON


JSON이란

jsonlogo
  • JSON은 JavaScript Object Notation의 약자이다.
  • 직관적이기 때문에 사람이 읽기 쉬우며 또한 컴퓨터 또한 읽기 쉽다.
  • JavaScript 스크립트 언어로부터 확장되었다.
  • JSON 인터넷 미디어 유형이 appilication/json이고 확장자는 .json이다.


왜 JSON을 사용해야 하는가

  • 네트워크 연결을 통해 구조화 된 데이터를 직렬화하고 전송하는데 사용된다.


특징

  • 읽고 쓰기가 쉽다.
  • 프로그래밍 언어로부터 독립적이다. (다른데로 이식하기도 쉽고 가져오기도 쉽다.)
  • 가벼운 텍스트 기반 교환 형식


JSON 개념

  • JSON Object : name, value pairs
  • JSON Array : ordered collections


JSON Data type

JSON Hierarchy


JSON 예제


1) Json data types

  • String, Number, Boolean, Null, Object, Array
<script>
	var who = { "name" : "Kim" };
  var age = { "age" : 30 };
  var car = { "car" : true };
  var middle = { "middle name" : null };

  var personObj = { "name" : "kim", "age" : 30, "car" : true, "middle name" : null };
  var personList = { "list" : ["Kim", "Lee", "Park"]};
<script>

2) Accessing object

<script>
  var personObj = { "name" : "kim", "age" : 30, "car" : true, "middle name" : null };
  var name1 = personObj.name;
  var name2 = personObj["name"];

  console.log(name1, name2);
<script>
  
// output : kim kim

3) Looping an object

var personObj = { "name" : "kim", "age" : 30, "car" : true, "middle name" : null}

for (x in personObj) {
  console.log(x, personObj[x]);
}

// output
// name kim
// age 30
// car true
// middle name null

4) Nested Objects

var personObj = { "name" : "kim", 
                 "age" : 30, 
                 "car" : {
                   "car1" : "Hyundai",
                   "car2" : "Kia",
                   "car3" : "Chevrolet"
                 }
                };

console.log(personObj.car.car1);

// output : Hyundai

5) Modify values

var personObj = { "name" : "kim", 
                 "age" : 30, 
                 "car" : {
                   "car1" : "Hyundai",
                   "car2" : "Kia",
                   "car3" : "Chevrolet"
                 }
                };
personObj.car.car1 = "Mercedes";
console.log(personObj.car.car1
            
// output : Mercedes

6) Delete object properties

var personObj = { "name" : "kim", 
                 "age" : 30, 
                 "car" : {
                   "car1" : "Hyundai",
                   "car2" : "Kia",
                   "car3" : "Chevrolet"
                 }
                };
delete personObj.car.car3;

console.log(personObj.car);

// output : {car1 : "Hyundai", car2 : "Kia"}

7) Accessing array values

var personObj = { "name" : "kim", "age" : 30, 
                 "car" : ["Hyundai", "Kia", "Chevrolet"]};

console.log(personObj.car[0]);

// output : Hyundai

8) Looping through an array

var personObj = { "name" : "kim", "age" : 30, 
                 "cars" : ["Hyundai", "Kia", "Chevrolet"]};

for (x in personObj.cars) {
  console.log(personObj.cars[x]);
}

// Hyundai
// Kia
// Chevrolet

for (i=0; i<personObj.cars.length; i++)
  console.log(personObj.cars[i]);
  
// Hyundai
// Kia
// Chevrolet

9) Nested arrays

var personObj = { "name" : "kim", "age" : 30, 
                 "cars" : [
                   {"name":"Hyundai","models":["Avante","Sonata","grandeur"]},
                   {"name":"Kia","models":["K3","K5","K7"]},
                   {"name":"Chevrolet","models":["Cruze","Malribu","impala"]}
                 ]};

for (i in personObj.cars) {
  console.log(personObj.cars[i].name);
}

// Hyundai
// Kia
// Chevrolet

for (j in personObj.cars[i].models)
  console.log(personObj.cars[i].models[j]);

// Cruze
// Malribu
// impala

10) Delete array items

  • shift, pop, splice
delete personObj.cars[2].models[0];
console.log(personObj.cars);

// [{...}, {...}, {...}]

delete personObj.cars[2];
console.log(personObj.cars);

// [{...}, {...}, empty]

// {...}에는 각 인덱스에 맞는 정보가 들어있음


11) Stringify

  • JSON의 사용은 웹서버__로/부터 데이터를 교환__하는 것이다.
  • 웹 서버로 데이터를 보낼 때, 데이터는 문자열이어야한다.
JSON.stringify(value[, replacer[, space]])
  • value - JSON 객체를 JSON 문자열로 바꿔준다.
  • replacer - 문자열 처리 프로세스의 동작을 변경하는 함수이다. 만약 이 값이 null 이거나 제공되지 않았다면, 이 객체의 프로퍼티들은 JSON 문자열에 포함된다.
  • space -가독성을 위해 JSON 문자열 출력에 공백을 삽입하는데 사용되는 문자열 또는 숫자 객체이다. 만약 숫자라면, 이것은 공백에 사용할 공백 문자 수를 나타낸다.


(1) Javascript object

var obj = { name : "kim", "age" : 30, "car" : true};

console.log(obj);
// { name : "kim", "age" : 30, "car" : true}
console.log(JSON.stringify(obj));
// { "name" : "kim", "age" : 30, "car" : true}

objStr = JSON.stringify(obj);

console.log(obj.name);
// kim
console.log(objStr.name);
// undefined

####(2) Javascript array

var arr = [ "Kim", 30, true];

console.log(arr);
console.log(JSON.stringify(arr));
// ["Kim", 30, true]
// ["Kim", 30, true]

arrStr = JSON.stringify(arr);

console.log(arr[0]);
console.log(arrStr[0]);
// Kim
// []

(3) replacer,space

var obj = { name : "Kim", "age" : 30, "car" : true};

console.log(obj);
console.log(JSON.stringify(obj));

// { name : "Kim", "age" : 30, "car" : true}
// { "name" : "Kim", "age" : 30, "car" : true}

objStr = JSON.stringify(obj, ["name"]);

console.log(obj);
console.log(objStr);
// { name : "Kim", "age" : 30, "car" : true}
// { "name" : "Kim"}

objStr = JSON.stringify(obj, function(k,v) {if (v=="Kim") return ; else return v;});

console.log(obj);
console.log(objStr);
// { name : "Kim", "age" : 30, "car" : true}
// {"age":30, "car":true}

objStr = JSON.stringify(obj, null, 10);

console.log(obj);
console.log(objStr);
// { name : "Kim", "age" : 30, "car" : true }
// {
//           "name":"Kim",
//           "age":30,
//           "car":true
// }

12) parse

  • JSON의 사용은 웹서버__로/부터 데이터를 교환__하는 것이다.
  • 웹 서버로부터 데이터를 받을 때, 데이터는 항상 문자열이다.
JSON.parse(text[, reviver])
  • text - JSON 객체로 파싱할 문자열
  • reviver - 리턴되기 전, 파싱에 의해 원래 값이 어떻게 생성되는지를 정하는 함수.
var script = '{ "name" : "Kim", "age" : 30, "car" : ["Ray", "Spark"]}';

console.log(str);
console.log(str.name);
// { "name" : "Kim", "age" : 30, "car" : ["Ray", "Spark"]}
// undefined

obj = JSON.parse(str);

console.log(obj);
console.log(obj.name);
// { name : "Kim", "age" : 30, "car" : Array(2)}
// Kim

13) Reviver

var script = '{ "name" : "Kim", "age" : 30, "car" : ["Ray", "Spark"]}';

console.log(str);
console.log(str.name);
// { "name" : "Kim", "age" : 30, "car" : ["Ray", "Spark"]}
// undefined

obj = JSON.parse(str);

console.log(obj);
console.log(obj.age);
// { name : "Kim", "age" : 30, "car" : Array(2)}
// 30


JSON with Python


  • JSON library : import json
  • Encoding : dump, dumps
  • Decoding : load, loads


Data types

python JSON
dict object
list, tuple array
str string
int, float, int- & float-derived Enums number
True true
False false
None null

dump/dumps

name = ("Kim", "Lee", "Park")
age = [ 30, 28, 31]
person = {"name":"Kim", "age":30, "car":False}

nameStr = json.dumps(name)
ageStr = json.dumps(age)
personStr = json.dumps(person, indent="  ")

kname = ("김", "이", "박")
knameStr = json.dumps(kname)
print(kanameStr)

knameStr = json.dumps(kname, ensure_ascii=False)
print(knameStr)


load/loads

personObj = json.loads(personStr)
person == personObj


with a file

person["car"] = ["레이", "모닝"]

with open("person.json", "w") as f:
    json.dump(person, f)
with open("person.json", "r") as f:
    personObj = json.load(f)
    
personObj


예제

import json
import urllib.request

url = "http://li.jsontest.com"

obj = { "name":"김이박", "age":30 }
objStr = json.dumps(obj)
objByte = objStr.encode("utf-8")

req = urllib.request.Request(url, data=objByte, headers={'content-type' : 'application/json'})
res = urllib.request.urlopen(req)

resByte = res.read()
resStr = resByte.decode("utf-8")
resObj = json.loads(resStr)

print(resByte, type(resByte))
print(resStr, type(resStr))
print(resObj, type(resObj))


공공데이터 로pen API로 데이터 가져오기


  • 이용 사이트 : 공공데이터
  • 가져오고 싶은 데이터 선택 후 인증키까지 발급하기
  • URL end-point 알아내기
  • urllib 문서
import urllib
import json

url = "http://openapi.airkorea.or.kr/openapi/services/rest/ArpltnInforInqireSvc/getMsrstnAcctoRltmMesureDnsty"

# 필요한 파라미터
params = {
    "serviceKey" : "각자 키",
    "numOfRows" : 10,
    "pageSize" : 10,
    "pageNo" : 1,
    "startPage" : 1,
    "stationName" : "성북구",
    "dataTerm" : "DAILY",
    "ver" : "1.3",
    "_returnType" : "JSON"
}

params["serviceKey"] = urllib.parse.unquote(params["serviceKey"])
params = urllib.parse.urlencode(params)
params = params.encode("utf-8")

# get 방식으로 url 날림
req = urllib.request.Request(url, data=params)
# request 객체 만들어서 보냄.
res = urllib.request.urlopen(req)

resStr = res.read()

# encode, decode 쌍임
resStr = resStr.decode("utf-8")
resObj = json.loads(resStr)

resJSON = json.dumps(resObj, indent="   ")

print(resJSON)
  • urllib.parse.unquote() : 선택적 인코딩 및 오류 파라미터는 bytes.decode() 메소드에 의해 허용된 대로 백분율로 인코딩된 시퀀스를 유니코드 문자로 디코딩하는 방법을 지정한다.
  • urllib.parse.urlencode) : str 또는 byte 객체를 포함할 수 있는 매핑 객체 또는 두 요소 튜플 시퀀스를 백분율로 인코딩 된 아스키 텍스트 문자열로 변환한다.
  • str.encode() : string의 인코딩된 version을 __bytes 객체__로 돌려준다. 기본 인코딩은 ‘utf-8’이다.
  • urllib.request.Request(url, data, ...)
    • url : 유효한 url
    • data : 서버로 보낼 추가 데이터를 지정하는 객체
  • urllib.request.urloepn(url, ..) : url에 대한 객체를 돌려준다.
// output
{
   "list": [
      {
         "_returnType": "json",
         "coGrade": "1",
         "coValue": "0.5",
         "dataTerm": "",
         "dataTime": "2019-07-11 20:00",
         "khaiGrade": "1",
         "khaiValue": "32",
         "mangName": "\ub3c4\uc2dc\ub300\uae30",
         "no2Grade": "1",
         "no2Value": "0.019",
         "numOfRows": "10",
         "o3Grade": "1",
         "o3Value": "0.014",
         "pageNo": "1",
         "pm10Grade": "1",
         "pm10Grade1h": "1",
         "pm10Value": "3",
         "pm10Value24": "7",
         "pm25Grade": "1",
         "pm25Grade1h": "1",
         "pm25Value": "2",
         "pm25Value24": "3",
         "resultCode": "",
         "resultMsg": "",
         "rnum": 0,
         "serviceKey": "",
         "sidoName": "",
         "so2Grade": "",
         "so2Value": "-",
         "stationCode": "",
         "stationName": "",
         "totalCount": "",
         "ver": ""
      },
      {
         "_returnType": "json",
         "coGrade": "1",
         "coValue": "0.5",
         "dataTerm": "",
         "dataTime": "2019-07-11 19:00",
         "khaiGrade": "1",
         "khaiValue": "33",
         "mangName": "\ub3c4\uc2dc\ub300\uae30",
         "no2Grade": "1",
         "no2Value": "0.013",
         "numOfRows": "10",
         "o3Grade": "1",
         "o3Value": "0.020",
         "pageNo": "1",
         "pm10Grade": "1",
         "pm10Grade1h": "1",
         "pm10Value": "6",
         "pm10Value24": "8",
         "pm25Grade": "1",
         "pm25Grade1h": "1",
         "pm25Value": "2",
         "pm25Value24": "4",
         "resultCode": "",
         "resultMsg": "",
         "rnum": 0,
         "serviceKey": "",
         "sidoName": "",
         "so2Grade": "",
         "so2Value": "-",
         "stationCode": "",
         "stationName": "",
         "totalCount": "",
         "ver": ""
      },
      ...
}

이처럼 딕셔너리 형태로 가져오기 때문에 key 값들만 보고 싶다면

resObj.keys()

# output
# dict_keys(['list', 'parm', 'ArpltnInforInqireSvcVo', 'totalCount'])

을 입력하면 된다.

만약 ‘list’에 있는 pm25Value 만 출력하고 싶다면

for x in range(10):
    print(resObj["list"][x]["pm25Value"])

이렇게 입력하면 된다.

타입 확인은 아래처럼 하면 된다.

[(k, type(resObj[k])) for k in resObj.keys()]

Comments