brunch

You can make anything
by writing

C.S.Lewis

by 김영하 Dec 05. 2024

중앙선거관리위원회 선거공약정보 분석해보기 2

공공데이터 분석

https://www.data.go.kr/data/15040587/openapi.do

지난 시간에 "중앙선거관리위원회 선거공약정보" 데이터를 살펴보았습니다. 이 데이터를 활용하기 위해서는 선거ID, 선거종류코드를 위해서는 "중앙선거관리위원회 코드정보"가 필요하다는 것을 인식하게 되었습니다.


https://www.data.go.kr/data/15000897/openapi.do?recommendDataYn=Y

그래도 일단 "중앙선거관리위원회 선거공약정보" 데이터 수집해 보겠습니다.


해당 페이지로 이동하면 XML 및 JSON 형태를 데이터를 수집하기 위해서는 API 방식으로 호출을 해야 한다고 합니다. 또한, 이 API을 호출하기 위해서는 서비스키가 필요한데 활용신청을 해야 한다고 합니다. 화면에서 "활용신청"을 클릭합니다. 이 때, 공공데이터포털에 로그인되어 있는 상태이어야 합니다.



위 화면에서 활용목적을 입력하고, 이용허락범위에서 "동의합니다"를 선택합니다.


마지막으로 "활용신청"을 클릭합니다. 바로 승인이 됩니다. 



활용신청현황에 신청한 "중앙선거관리위원회 선거공약정보"가 추가된 것을 볼 수 있습니다.



"중앙선거관리위원회 선거공약정보"를 클릭하면 위와 같이 상세 내용을 볼 수 있고, 서비스 API호출에 중요한 일반 인증키(Encoding)와 일반 인증키(Decoding)를 부여받을 것을 볼 수 있습니다. 여기에서 일반 인증키를 데이터를 호출할 때 사용합니다.


API 호출에 대한 참고 문서를 위 화면에서 다운로드해서 볼 수 있습니다.


이제 데이터 수집을 위해 코딩을 해보겠습니다.


https://gist.github.com/fermat39/e4292080e3fa5bd5f32b5c0c8d1f5184


1행에서 API 호출을 위해 requests 라이브러리를 불러옵니다.

2행에서는 API 호출 결과를 JSON 형식으로 받고, 처리하기 위해서 json 라이브러리를 불러옵니다.

3행에서는 데이터를 쉽게 처리하기 위해 데이터 처리에 많이 사용하는 판다스 라이브러리를 불러옵니다.


https://gist.github.com/fermat39/39e9aeeb9e83cc855af8a339f590561f


1행에서는 API 호출을 하면 최대 100행을 불러올 수 있습니다. API로 데이터를 불러오면 totalCount에서 데이터의 총 개수를 알 수 있습니다. 반복할 호출 회수를 계산하기 위해 MAX_ROWS에 100을 저장합니다.

2행에서는 "중앙선거관리위원회 선거공약정보" 데이터를 얻어오는 URL 주소를 저장합니다.

3행에서는 호출시 필요한 파라미터를 파이썬 딕셔너리 방식으로 PARAMS에 저장합니다. 이번 호출에는 데이터의 총 갯수를 얻어오기 위해 필수 parameter 중에서 numOfRow, pageNo에 각각 1을 저장하고, serviceKey에는 이전에 신청해서 승인받은 일반 인증키(Decoding)을 저장합니다. resultType은 필수 항목은 아니지만, json으로 할당하지 않으면, XML 형식으로 데이터를 가져오기 때문에 지정했습니다.

5행에서 URL호출을 하는데 이 때, 미리 지정한 PARAMS을 전달합니다.



호출 결과는 위와 같습니다.


https://gist.github.com/fermat39/09ed1ebd8b74911b36079279d5baa059


호출 결과를 보면 totalCount에 172라고 되어 있습니다. 이 totalCount를 이전에 저장한 MAX_ROWS로 나누면 2라는 결과를 얻을 수 있습니다. 반복으로 2번 호출을 하면 총 172개 데이터를 얻을 수 있습니다. 2번 호출한다는 정보를 TOTAL_PAGES에 저장합니다.


https://gist.github.com/fermat39/71ba0eb7c245a396e7afea011f3acbfb


1행에서 호출한 API의 데이터를 판다스 데이터프레임에 저장하기 위해 비어 있는 df를 생성합니다.

3행 ~ 8행에서는 이전에 얻는 반복 횟수만큼 반복합니다. range(TOTAL_PAGES)는 TOTAL_PAGES가 2이기 때문에 0, 1 총 2번 반복합니다. 그래서 PARAMS에서 PAGE에 1씩을 더해 줍니다. 1번 호출할 때, 최대 데이터 행은 100개이기 때문에 이전에 저장한 MAX_ROWS를 전달합니다. 받아온 데이터 response를 파이썬에서 다룰 수 있는 json 형태로 변환하고, response -> body -> items -> item를 key로 해서 데이터를 가져와서 이전에 생성한 df에 추가해 줍니다. 실행하면 결과는 172개 행에 5개 컬럼이 있다는 것을 알 수 있습니다.


https://gist.github.com/fermat39/0949bdf9a160528f37b1949655c2fded


1행을 실행하면, 'num', 'sgId', 'sgName', 'sgTypecode', 'sgVotedate'라는 컬럼이 존재한다는 것을 알 수 있습니다.


https://gist.github.com/fermat39/c90b12932871883fc74977e5af97f49c


이 중에서 선거 이름 (sgName)과 선거 종류 코드 (sgTypecode)를 알아보기 위해 데이터프레임 df에서 해당 2개 컬럼만 가져오고 중복을 제거 (drop_duplicates())를 합니다. 이어서 sgTypecode, sgName순으로 정렬(sort_values())합니다.


결과입니다!


아... 역시 데이터를 항상 의심을 해봐야 합니다!!! 항상 쉽게 가는 것이 없군요!!!


83 구,시,군의 장선거11 구,시,군의장선거를 보면 왠지 중복 데이터 같습니다.


다음에는 이 결과를 찾아보고 데이터 분석에 지장을 주는 지저분한 (dirty) 데이터를 한번 처리해 보겠습니다!!!

브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari