공공데이터를 가지고 의류수거함의 위치를 조회할 수 있는 기능을 만들고자 한다.
서울시 12개구의 의류수거함 위치 정보를 데이터베이스에 담아놓고 구, 동의 정보를 query로 조회했을 때 해당하는 위치 데이터 리스트를 볼 수 있는 기능이다.
이 포스트는 해당 기능을 구현하기 위해 데이터를 전처리하는데에 필요한 과정만을 담았다. 나머지 카카오맵 API를 브라우저에 그리는 기능은 추후 다른 포스팅으로 보충할 예정이다.
토이 프로젝트를 계속해서 하다보면은 기획에서 계속해서 마주치는 문제점이 있다.
그것은 서비스를 위한 데이터 수집이다.
사용자가 직접 데이터를 만드는 경우라면 배포를 하더라도 데이터가 없기 때문에 fake user 및 fake data를 만드는 것이 불가피하다.
그런 경우가 아니라면 이미 존재하는 데이터를 제공하는 서비스를 생각할 수 있는데,
이럴 경우 존재하는 데이터를 어디서, 어떻게 갖고 오느냐가 쟁점인 것이다.
그래서 이번 프로젝트에서는 공공데이터를 활용해보기로 생각했다.
앞으로 이야기할 기능 구현에 있어서 사용한 스택은 다음과 같다.
우선 모으고 싶은 공공데이터가 어떤 정보를 가지고 있는지 확인한다.
필자의 경우 의류수거함의 위치 정보, 특히나 서울특별시의 12개구를 지정하여 수집했다.
혹여나 카카오맵 API를 이용하고 싶은데 다른 위치 데이터를 전처리하려는 사람이 이 글을 읽고 있다면
데이터에 위도, 경도가 있으면 베스트,
없더라도 상관 없지만 도로명 주소가 반드시 포함된 데이터를 준비하길 바란다.
더불어서 해당 글은 csv 파일을 가지고 데이터 전처리를 하는 과정을 담았으니
JSON과 같은 그 외 형식이라면 과정이 별도로 추가되어야 함을 알려드린다.
우선 csv 파일이 준비되었다는 가정하에 google drive 내에 폴더를 하나 생성하여 다음과 같이 정형화된 이름(ex. NN구
)으로 저장한다.
마지막 파일은 추후 생성하는 Google Colab
파일이니 무시한다.
카카오맵 API를 쓰려면 key를 발급 받아야 한다.
다소 헷갈리는 부분들이 있지만 그래도 어렵지 않으니 그대로 따라오길 바란다.
카카오 디벨로퍼스에 접속한 다음에,
먼저 API를 사용할 애플리케이션을 만든다.
아래 가려둔 key 값 중 REST API 키, JavaScript 키는 쓸 예정이기 때문에 탭을 별도로 띄워두거나 메모장에 복사-붙여넣기 해놓으면 편할 것이다.
정확히 얘기하자면, 데이터 전처리할 때는 REST API 키
만 있으면 된다.
앞서 제시한 예시처럼 카카오맵을 띄우는 SDK를 사용할 예정이라면, JavaScript 키가 별도로 필요하다.
플랫폼 설정하기를 클릭한다.
JavaScript SDK, 카카오톡 공유, 카카오맵 사용시 등록이 필요하기 때문에 반드시 설정해주어야 한다.
지금은 당장 app 개발로 들어가는 것이 아니지만 우선 임시로 http://localhost:3000
으로 설정해두면 된다.
카카오 디벨로퍼스 문서를 찬찬히 읽다보니 다음과 같은 기능을 제공하는 것을 알 수 있었다.
그래서 공공데이터를 수집할 때 발생했던 문제점을 해결할 수 있다고 판단했다.
공공데이터들은 몇 개만 펼쳐 봐도 산발적으로 되어있는 것을 알 수 있었고,
그나마 공통적으로 가지고 있던 것은 [행정동/도로명 주소]뿐이었다.
이마저도 도로명 주소에 <'서울특별시'가 포함된 경우/포함되지 않는 경우/'구'가 포함되지 않는 경우> 등 케이스가 다양하여 주소명이 통일되지 않았다.
관계형 DB로 쌓으려고 했고, 최대한 null값이 들어가지 않도록 해야했기 때문에,
없는 column에 대한 데이터는 새로 넣고, 불필요한 column은 제외시키고자 했다.
처음에는 공통 정보 위주로만 데이터베이스에 넣으려고 했다.
그런데 전처리를 하던 와중 카카오맵 API를 보니 다음 항목을 확인할 수 있었다.
즉, 카카오맵 API로 호출한 결과로 나오지 않았을 경우 마커가 표시되지 않는 것이다.
그렇다면 데이터베이스에 있는 주소를 조회했을 때 결과 없어서 아무 반응이 뜨지 않는 것보다는
처음부터 데이터베이스에서 제외시키는 게 낫지 않을까하고 판단했다.
따라서 데이터베이스 column으로 좌표값(위도, 경도)을 추가했다.
더불어서 추후 주소 데이터의 조회 및 등록이 확장될 수 있다는 것을 대비하여 primary key를 별도로 UUID로 지정해주었다.
빠르게 데이터를 import-export하기 위해서 브라우저 내에서 python 스크립트를 실행시킬 수 있는 google colab을 선택했다.
google colab은 google drive에서 간단하게 시작할 수 있다.
아래 이미지와 같이 drive 중 colab file을 저장하고 싶은 곳에서 오른쪽 클릭/더보기에 들어가면 Google Colaboratory
가 보이는데, 이를 클릭하면 된다.
자세한 사용방법: Why and how to use Google Colab - TechTarget
구체적인 사용 방법이나 문법은 제외하고, 코드 구성 위주로 설명하겠다.
encoding = 'cp949'
는 한글 인코딩 에러가 발생하는 경우 추가하면 된다.
다음은 카카오맵 API를 이용해서 x, y 좌표가 없는 데이터의 경우 보충하는 함수이다.
python 내장 라이브러리 중 HTTP 요청을 할 수 있는 requests
를 이용했다.
더불어서 카카오 디벨로퍼스 문서를 참고해 request query를 세팅했다.
다음은 구 별로 csv 파일을 받았을 때 실행하는 함수들 중 예시를 몇 가지 가져왔다.
전체 코드는 포스트 가장 하단에 레포지토리 링크로 첨부하였다.
의류수거함
column에 불필요하게 -${번호}
형태로 추가되어 있어 map+lambda
로 제거해주었다.get_XY_from_addr
를 사용했다.주소
에 '서울특별시'가 아닌 '서울'로 되어 있어서 replace
로 통일시켜주었다.dropna
를 통해 데이터를 제외시켰다.그리고 참고로 현재 (23년 12월 21일 기준) 금천구 데이터에서 위도, 경도가 뒤바뀌어 있는 상황이므로 주의해서 전처리를 해야한다.
일단 데이터 오류 신고를 해놓은 상태이긴 하다!
업데이트: 24.01.08
업데이트되었으니 예외 처리 안해도 됩니다.
for문을 세 부분으로 나눈 이유는 어떤 구의 경우 데이터가 몇 백 개 가까이 되기 때문에 시간이 오래 걸린다.
도중에 데이터가 잘못 된 경우, 네트워크 오류가 생기는 경우, Google Colab 자체의 연결이 끊기는 경우 등 다양하게 코드가 중지되는 경우가 있기 때문에 각각의 부분에서의 중지점을 마련한 것이라고 보면 된다.
전처리 실행 로직이 다 돌고 나면 이제 csv로 추출할 준비가 된 것이다.
추출하기 전 잠깐!
혹시 동일하게 mysql을 쓰고 있다면 JSON으로도 함께 추출하는 것을 추천한다.
왜냐하면 mysql에서는 cp949 설정을 지원하지 않아서 utf-8로 다시 바꿔주어야 하기 때문이다.
그런 다음 mysql workbench에 접속하여 직접 import하면 된다.
트러블 슈팅 참고: [MySQL] MySQL 워크벤치로 json 파일 import 하기
더불어서 위 링크에서 언급한 0 record imported
문제가 동일하게 발생했었는데, 역시 경도, 위도 데이터를 map
을 이용해 문자열 형태로 변환했더니 정상적으로 데이터가 들어갔다.
알맞게 전처리된 JSON 파일이 준비됐다는 가정하에 다음의 단계를 거치면 이제 끝이다!
원하는 Table 위에 오른쪽 클릭으로 Table Data Import Wizard
를 연다.
저장한 json 파일을 부른 다음 기존의 table에 데이터를 넣을 것인지, 새로운 table을 만들 것인지 선택한다.
필자는 이미 table 초기 설정을 해놓았기 때문에 전자를 선택했다.
그런 다음 json의 key와 table의 column이 각각 일치하는지 확인한다,
Next를 누르고 기다리면 끝!
데이터 갯수에 따라서 오래 걸리기도 하는데, 처음 import할 때는 5,000개 데이터 기준 10분 정도 걸렸었다.
우왁! 잘 들어갔다!
웹 개발과는 잠시 거리가 멀어진 듯 하지만, 오랜만에 python을 써보기도 하고,
5,000개 이상의 데이터가 맘대로 차곡차곡 쌓이는 걸 보니 뿌듯하기도 했다.
지금 보기에 단계가 조금 간결한 듯 보이지만,
사실 처음부터 이렇게 간결하게 한 건 아니었다.
DataFrame 구조도 바꾸어보고, Table도 두 개로 만들었다가 다시 하나로 합치고,
문자열을 가공하는 로직도 혼재되어 있었으며,
특히나 csv, JSON 파일을 export, import할 때 인코딩 설정에 애를 먹었었다.
그래도 산재된 데이터에서 필요한 것은 채우고, 필요없는 것은 제외시켜 정말로 필요한 것만 모아 하나의 Table로 만든 경험을 통해 많은 것을 배웠다.
다음에는 좀 더 복잡한 구조의 데이터를 가지고 만들거나, 다양한 API를 써보고 싶은 마음이 들었다.
다음 글에서는 React에서 카카오맵 JavaScript SDK를 이용해 실제 지도를 애플리케이션에 그리고 마킹하는 방법에 대해 이야기하고자 한다.