호쌤
호쌤 Just For Fun

[Python 데이터 수집] JSON 데이터 수집

크리에이티브 커먼즈 라이선스 ITPAPER(호쌤,쭈쌤)에 의해 작성된 ≪[Python 데이터 수집] JSON 데이터 수집≫은(는) 크리에이티브 커먼즈 저작자표시-비영리-동일조건변경허락 4.0 국제 라이선스에 따라 이용할 수 있습니다.
이 라이선스의 범위 이외의 이용허락을 얻기 위해서는 leekh4232@gmail.com으로 문의하십시오.

[Python 데이터 수집] JSON 데이터 수집

JSON은 경량의 데이터 표현 형식으로 최근에는 웹, 모바일 등을 중심으로 서로 다른 플랫폼간의 데이터 교환을 위하여 활용되고 있는 사실상의 산업 표준 입니다. 특히 OpenAPI등을 통해 다른 곳에서 제공하는 데이터를 수집할 경우 JSON 형식으로 되어 있는 경우가 많기 때문에 Python에서도 HTTP 통신을 기반으로 OpenAPI로부터 JSON 형식의 데이터를 수집하고 이를 데이터 프레임으로 변환하는 기능을 제공하고 있습니다.

#01. JSON 구조의 이해

key와 value의 쌍으로 이루어진 데이터 표현 형식으로 Python의 딕셔너리와 동일한 구조를 갖는다.

이름(key)와 값(value)의 쌍을 이루는 구조

1
{ "이름": "", "이름": "" ... }

값에는 숫자, 문자열, 논리값(true/false) 모두 가능하며 값이 문자열인 경우는 쌍따옴표나 홑따옴표로 감싸서 표현한다.

값을 배열 형식으로 구성가능

하나의 이름에 여러 개의 값을 포함시키고, 0부터 시작되는 인덱스 번호를 통해 값에 접근한다.

1
{ "이름": [ "값0", "값1", "값2" ] }

계층화 된 데이터의 표현

1
2
3
4
{
    "이름": { "이름": "", "이름": "" },
    "이름": { "이름": "", "이름": "" }
};

목록형 데이터의 표현

가장 일반적인 형식.

하나의 key에 대응되는 값이 배열 형태이고 배열의 각 원소가 동일한 구조를 갖는 JSON들로 구성된다.

article[0].subject –> 글 제목

1
2
3
4
5
6
{ "article" : [
    {"subject": "글 제목", "content": "글 내용", "writer": "작성자", "date": "작성일"},
    {"subject": "글 제목", "content": "글 내용", "writer": "작성자", "date": "작성일"},
    ...
    {"subject": "글 제목", "content": "글 내용", "writer": "작성자", "date": "작성일"}
]}

#02. 필요한 패키지 가져오기

1
2
3
4
import requests                # 통신 기능 제공
import json                    # 파이썬 내장 모듈
from pandas import DataFrame
from matplotlib import pyplot

03. 간단한 JSON 데이터 가져오기

requests 모듈이 지정된 URL의 내용을 모두 텍스트로만 가져오기 때문에 가져온 데이터의 형식에 따라 변환 처리가 필요하다.

1) URL 지정

1
simple_json_url = "http://www.itpaper.co.kr/demo/py/simple.json"

2) 세션생성

1
2
3
user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36"
session = requests.Session()
session.headers.update( {'User-agent': user_agent, 'referer': None} )

3) JSON 데이터 가져오기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 데이터 가져오기
r = session.get(simple_json_url)

# 결과 검사
if r.status_code != 200:
    # 에러코드와 에러메시지 출력
    print("[%d Error] %s" % (r.status_code, r.reason))
    # 프로그램 강제 종료
    quit()
    
# 인코딩 형식 지정 (대상 파일이 저장된 방식을 명시해야 함)
r.encoding = "utf-8"

# 텍스트 출력
print(type(r.text))
r.text
▶ 출력결과
1
2
3
<class 'str'>

'{\n    "name": "갤럭시 S6",\n    "type": "삼성",\n    "img": "http://itpaper.co.kr/demo/app/img/GalaxyS6.png"\n}'

4) JSON 형식의 문자열을 딕셔너리로 변환

파이썬 내장 패키지인 json 패키지의 loads() 함수를 사용하여 JSON 형식의 문자열을 딕셔너리 구조로 변환한다.

1
2
3
result = json.loads(r.text)
print(type(result))
result
▶ 출력결과
1
2
3
4
5
<class 'dict'>

{'name': '갤럭시 S6',
 'type': '삼성',
 'img': 'http://itpaper.co.kr/demo/app/img/GalaxyS6.png'}

5) 딕셔너리를 DataFrame으로 변환

DataFrame을 생성이 가능한 파라미터 형식

  1. 2차 리스트
  2. 모든 원소가 같은 크기의 리스트인 딕셔너리
    1
    
     {"a": [1, 2, 3, 4], "b": [10, 20, 30, 40] }
    
  3. 모든 원소가 같은 구조의 딕셔너리인 리스트
    1
    
     [ {"a": 1, "b": 2}, {"a": 10, "b": 20}, {"a": 100, "b": 200}]
    

    수신 결과는 단순한 딕셔너리 이므로 이 값을 통째로 리스트에 넣어줘야 한다. (3번 케이스와 호환)

1
2
simple_df = DataFrame([result])
simple_df
▶ 출력결과
name type img
0 갤럭시 S6 삼성 http://itpaper.co.kr/demo/app/img/GalaxyS6.png

#04. 리스트 형식의 데이터를 포함하는 JSON

1) 데이터 수집

JSON 가져오기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# JSON URL
json_list_url = "http://www.itpaper.co.kr/demo/py/student.json"

# 준비된 URL의 컨텐츠 가져오기
r = session.get(json_list_url)

# 접속에 실패한 경우에 대한 예외처리
if r.status_code != 200:
    print("[%d Error] %s" % (r.status_code, r.reason))
    quit()

# 인코딩 지정
r.encoding = "utf-8"

# 가져온 결과를 딕셔너리로 변환
result = json.loads(r.text)
result
▶ 출력결과
1
2
3
{'student': [{'name': '철수', 'math': 85, 'kor': 80, 'eng': 70},
  {'name': '영이', 'math': 92, 'kor': 70, 'eng': 85},
  {'name': '순이', 'math': 61, 'kor': 100, 'eng': 72}]}

데이터프레임으로 변환

가져온 결과에서 student키에 해당하는 리스트를 추출하여 데이터프레임으로 변환한다.

1
2
student_df = DataFrame(result['student'])
student_df
▶ 출력결과
name math kor eng
0 철수 85 80 70
1 영이 92 70 85
2 순이 61 100 72

2) 데이터 전처리

학생이름을 인덱스로 변경

1
2
3
4
5
6
7
8
9
10
11
12
13
# name 열의 값을 인덱스로 사용하기 위해 리스트 형식으로 추출
name_list = list(student_df['name'])

# 데이터 프레임의 rename 함수에 적용하기 위한 딕셔너리 생성
name_dict = {}
for i, v in enumerate(name_list):
    name_dict[i] = v

# 데이터 프레임의 인덱스, 컬럼이름 변경 및 name 컬럼 삭제
성적표df = student_df.rename(index=name_dict, 
               columns={"math": "수학", "kor": "국어", "eng": "영어"})
성적표df.drop('name', axis=1, inplace=True)
성적표df
▶ 출력결과
수학 국어 영어
철수 85 80 70
영이 92 70 85
순이 61 100 72

컬럼 순서 변경

1
2
성적표df = 성적표df.reindex(columns=["국어", "영어", "수학"])
성적표df
▶ 출력결과
국어 영어 수학
철수 80 70 85
영이 70 85 92
순이 100 72 61

3) 데이터 시각화

1
2
3
4
5
6
7
8
9
10
11
12
# 그래프를 만들기 위한 한글 폰트 설정
pyplot.rcParams["font.family"] = 'Malgun Gothic'
pyplot.rcParams["font.size"] = 16
pyplot.rcParams["figure.figsize"] = (14, 8)

# 전체 컬럼에 대한 시각화
성적표df.plot.bar(rot=0)
pyplot.grid()
pyplot.title("학생별 시험 점수")
pyplot.legend()
pyplot.ylabel("점수")
pyplot.show()
▶ 출력결과

png

Rating:

크리에이티브 커먼즈 라이선스 ITPAPER(호쌤,쭈쌤)에 의해 작성된 ≪[Python 데이터 수집] JSON 데이터 수집≫은(는) 크리에이티브 커먼즈 저작자표시-비영리-동일조건변경허락 4.0 국제 라이선스에 따라 이용할 수 있습니다.
이 라이선스의 범위 이외의 이용허락을 얻기 위해서는 leekh4232@gmail.com으로 문의하십시오.

comments powered by Disqus