JSON 데이터를 정제하는데 자꾸 해당하는 값이 없다고 에러가 떠요...

히제오·2020년 12월 17일
0

파이썬 til

목록 보기
6/9

잠깐, JSON 데이터란?

JSON(제이슨, JavaScript Object Notation)은 속성-값 쌍( attribute–value pairs and array data types (or any other serializable value)) 또는 "키-값 쌍"으로 이루어진 데이터 오브젝트를 전달하기 위해 인간이 읽을 수 있는 텍스트를 사용하는 개방형 표준 포맷이다. 비동기 브라우저/서버 통신 (AJAX)을 위해, 넓게는 XML(AJAX가 사용)을 대체하는 주요 데이터 포맷이다. 특히, 인터넷에서 자료를 주고 받을 때 그 자료를 표현하는 방법으로 알려져 있다. 자료의 종류에 큰 제한은 없으며, 특히 컴퓨터 프로그램의 변수값을 표현하는 데 적합하다.

'로그'의 형태로 사용자의 데이터를 수집할 때, 대부분 JSON 데이터인 것으로 보인다.

그렇다면, JSON 데이터는 어떻게 생겨먹었는지 잠깐 보자!

    {
        "client_msg_id": "44918F17-D312-4D0A-9D08-AD0C74B783BF",
        "type": "message",
        "text": "알겠습니당!!",
        "user": "U0180000",
        "ts": "1599046411.039600",
        "team": "T0183Q0000",
        "user_team": "T0183Q0000",
        "source_team": "T0183Q0000",
        "user_profile": {
            "avatar_hash": "57163f965edb",
            "image_72": "https:\/\/avatars.slack-edge.com/55.png",
            "first_name": "최뫄뫄",
            "real_name": "최뫄뫄",
            "display_name": "최뫄뫄",
            "team": "T0183Q0000",
            "name": "cupid1004",
            "is_restricted": false,
            "is_ultra_restricted": false
        },
        "blocks": [
            {
                "type": "rich_text",
                "block_id": "KSFw",
                "elements": [
                    {
                        "type": "rich_text_section",
                        "elements": [
                            {
                                "type": "text",
                                "text": "알겠습니당!!"
                            }
                        ]
                    }
                ]
            }
        ],
        "thread_ts": "1599015279.033400",
        "parent_user_id": "U018888",
        "reactions": [
            {
                "name": "conga_parrot",
                "users": [
                    "U018888"
                ],
                "count": 1
            }
        ]
    }

자바 스크립트의 문법이지만, 파이썬 문법으로 보았을 때는 리스트와 딕셔너리가 중첩된 형태로도 볼 수 있기 때문에, JSON 데이터를 파이썬에 불러와 데이터를 추출하는 방법이 가능하다.... 그러나! JSON 데이터의 가장 골치아픈 지점은 데이터가 RDBMS의 2차원 테이블 형태가 아니라는 것.... 그래서 그 때 그 때 사용자가 어떤 행동을 했느냐에 따라 JSON 로그의 형태가 달라질 수 있다.

위의 JSON 데이터를 다시 보면, 이 데이터는 슬랙에서 한 사람이 다른 사람의 메시지에 댓글을 단 행위에 대한 로그이다. parent_idthread_ts를 통해 댓글을 달았던 그 메시지의 정보를 보여주고 있다는 것으로 유추할 수 있다... 그말인즉슨, parent에 해당하는 user가 없고, thread에 속하지 않은 message의 경우 해당 부분 자체가 없는 데이터로 표현된다 parent_user_id: None 이런 형태 도 아니고, 아예 해당 dimension 자체가 없다는 뜻...

그 경우를 생각하지 못하고 데이터 추출을 위한 for문을 돌리면 그 부분의 값 자체가 없다는 error를 맞이할 수 있다. 그럴 땐, 당황하지 말고 "아 구별 기준이 될만한 요소를 하나 찾았구나..." 하고 생각해보자.

해당하는 value가 없다면... get() 함수로 해결하기

for문에 print 함수를 적절히 넣어 문제 지점을 직접 확인한 뒤, 값이 없다는 에러를 패스하고 추출하기를 원한다면, 아래와 같이 코드를 짜볼 수 있다.


            # reaction에 대한 정보 수집
            if slack[x].get('reactions') != None:
            	# reactions에 대한 정보 추출해서 리스트에 해당 값 입력하는 코드

            else:
            	# reactions에 대한 리스트에 0을 입력하는 코드
			

slack message x번째 로그에 'reactions'라는 이름을 가진 딕셔너리가 None이 아니라면 해당 정보를 추출해 리스트에 집어넣고, None이라면 정보를 추출하는 대신 리스트에 0을 집어넣는 코드이다. slack[x]['reactions']으로 쓸 수 없는 이유는, 'reactions'라는 이름의 딕셔너리가 없을 때 None을 뱉어내는 것이 아니라 Error를 뱉어내며 동작이 멈춰버리기 때문이다...

이게 데모데이 TIL인 이유는...

데모데이 때 사용했던 배틀그라운드 로그데이터도 비슷한 이슈가 있었다. flynn씨의 모듈을 사용해서 JSON 데이터를 사용했기 때문에, 비슷한 경우에도 이렇게 처리할 수 있었다.

            if kill[e].killer is None:
                continue

JSON 형태의 데이터를 가공하는 일... 꽤 어렵지만 도전의식을 자극하기도 해서 은근 재밌다 🤓

profile
삽질 전문가. 모든 일에 진심인 편.

0개의 댓글