본문 바로가기
연습장/Open API

[Kakao] 카카오 API를 활용한 경도/위도 데이터 수집

by Ruas 2023. 6. 26.
728x90

오늘 살펴볼 것은 주소 데이터를 활용한 경도/위도 수집 방법이다.

 

경도/위도 데이터를 얻는 방법은 사실 API를 사용하지 않아도 구글 맵에서 충분히 얻을 수 있다.

 

Source: Google map

위의 사진과 같이 경도/위도 데이터를 얻을 수 있다.

하지만 위의 방식은 다량의 데이터를 수집해야하는 경우에는 너무 부적합하다는 문제가 있다.

 

이를 해결하기 위해 지번, 도로명 주소를 전달하면 경도/위도 값을 반환해주는 카카오 지도 API를 사용해보고자 한다.


1. Dataset 선정

API를 사용하기 전, API에 전달할 데이터를 구해야한다.

API를 사용해서 경도/위도 데이터를 얻기 위해서는 정확한 지번, 혹은 도로명 주소가 필요하다.

조금이라도 오염이 되었거나, 정확하지 못한 주소가 입력되어 있는 경우에는 데이터를 얻을 수 없다.

이점 유의해서 희망하는 데이터를 선정하면 된다.

 

해당 포스트에서는 한국관광공사에서 제공하는 전국문화축제표준데이터에서 

경도/위도 데이터가 누락된 축제 데이터를 별도로 가공하여 사용한다.

 

 

전국문화축제표준데이터

국가에서 보유하고 있는 다양한 데이터를『공공데이터의 제공 및 이용 활성화에 관한 법률(제11956호)』에 따라 개방하여 국민들이 보다 쉽고 용이하게 공유•활용할 수 있도록 공공데이터(Datase

www.data.go.kr

 

해당 데이터에는 경도/위도 데이터가 있는 데이터와 없는 데이터가 섞여있어, 별도의 가공 절차가 필요하다.

가공 절차에 대해서는 별도로 설명하지 않고 진행하겠다.

 

✅ 해당 데이터에는 이미 경도/위도가 포함되어 있다.

✅ 하지만 일부 경도/위도 데이터가 유실된 상태이기 때문에 Dataset으로 선정했다.

✅ 해당 데이터에는 주소가 잘못입력되어 있는 케이스가 존재하기 때문에 별도 수정 작업이 필요하다.


2. 데이터 불러오기

import geopandas as gpd

check_data = gpd.read_file('경위도확인필요.csv')

geopandas 라이브러리를 활용하여 1번 과정에서 가공한 csv 파일을 데이터프레임 형식으로 불러온다.

불러온 데이터는 check_data 데이터 프레임에 저장하는 방식으로 진행한다.

 

위의 사진은 불러온 데이터의 일부분이다.

사진에서 알 수 있듯이 위도, 경도 데이터가 모두 비어 있는 것을 확인할 수 있다.


3. API Setting - Kakao Developers

 

[Kakao] Open API 사용 준비

카카오와 네이버와 같은 it 기업에서는 자사 서비스를 보다 편하게 사용할 수 있도록 하는 Open API 를 제공한다. 검색 엔진을 사용하는 키워드 검색 기능, 지도 검색, 자사 계정을 사용한 로그인

ruas-coding.tistory.com

카카오 API 설정은 위의 글을 참조하기 바란다.

 

이번 글에서 사용할 KakaoMap API의 경우 REST API를 사용하기 때문에 해당 키를 복사해두면 된다.


4. API 설정

def search(text):
    api_key = "YOUR_RESTAPI_KEY"
    url = 'https://dapi.kakao.com/v2/local/search/address.json'
    text = ul.parse.quote(text)
    query = "query="+text
    query_str = f'{url}?{query}'
    request = req.Request(query_str)
    request.add_header("Authorization","KakaoAK "+api_key)
    resp = req.urlopen(request)
    
    if resp.getcode()!=200:
        return None
        
    data = resp.read()
    jdata = json.loads(data)
    items = jdata['documents']

    return [Locale.json2locale(item) for item in items]

검색 API에는 카카오 API를 사용한 검색기능을 구현한다.

때문에 위에서 언급했던 API 키가 필요하다.

 

Source: Kakao Developers

 

우리는 카카오 맵 API에 지번/도로명 주소를 전달하여 다른 데이터를 구하고자 하는 것이기 때문에,

https://dapi.kakao.com/v2/local/search/address.json

해당 주소로 데이터를 전송해야 한다.

 

여기서 중요한점은 API가 요구하는 format에 맞추어 데이터를 전송해야하기 때문에 Document 확인이 필수적이다.

잘못된 형식으로 전송하는 경우 정상적으로 동작하지 않기 때문에 API를 사용하기 전에 한번 확인하는 것을 추천한다.

 

API에 관한 자세한 설명은,

 

Kakao Developers

카카오 API를 활용하여 다양한 어플리케이션을 개발해보세요. 카카오 로그인, 메시지 보내기, 친구 API, 인공지능 API 등을 제공합니다.

developers.kakao.com

위의 링크에서 확인할 수 있다.

 

현재 API에서 반환되는 데이터들은 모두 JSON 타입으로 되어있다.

때문에 이를 가공해서 사용하기 위해서는 JSON 타입의 데이터를 먼저 변환해야한다.

이 역할을 하는 것이 바로 다음 코드이다.

data = resp.read()
jdata = json.loads(data)
items = jdata['documents']

5. 데이터 가공

4번 단계에서 가져온 데이터를 데이터프레임에 삽입하기 위해서는 가공 과정을 거쳐야한다.

가공 과정을 위해서는 API에서 반환하는 파라미터들의 종류를 알아야한다.

파라미터 역시 Documents를 확인하면 있으니 꼭 읽어봐야한다.

Source: Kakao Developers

여기서 우리가 필요한 데이터는  longtitude와 latitude 데이터인데,

어느 주소의 데이터인지 명확하게 하기 위해 address_name도 같이 불러오도록 하겠다.

 

class Locale:
    def __init__(self,addr,lng,lat):
        self.addr = addr
        self.longitude = lng
        self.latitude = lat
    @staticmethod
    def json2locale(item):
        addr = item['road_address']
        lng = item['x']
        lat = item['y']
        return Locale(addr,lng,lat)
    def write(self,fs):
        fs.write(self.addr)
        fs.write(",")
        fs.write(self.longitude)
        fs.write(",")
        fs.write(self.latitude)
        fs.write('\n')

search 함수에서 받아온 JSON 데이터를 하나씩 Locale class의 json2locale 함수로 전달한다.

이 과정을 거치면서 주소, 위도, 경도 데이터가 각각 분리된다.

여기서 주소가 road_address로 되어 있는 것은 편의상 지번/도로명 주소를 구분하지 않고 진행했다.

 

위 과정에서 얻은 경도/위도 데이터는 각 변수에 저장되어 이후 기술할 코드에서 사용한다.


6. 주소 검색

본격적으로 데이터프레임에 있는 주소를 활용, 경도/위도 데이터를 받아올 차례이다.

for i in range(len(check_data)):
    print("[",i,"] Searching...", check_data['소재지도로명주소'][i])
    locales = lonlat.search(check_data['소재지도로명주소'][i])
    for locale in locales:
        check_data['위도'][i] = locale.latitude
        check_data['경도'][i] = locale.longitude

데이터 프레임의 주소 데이터만을 가지고와 search 함수로 전달,

search 함수는 검색 결과를 locale class의 함수로 전달하여 각 변수로 저장한다.

 

이후 데이터프레임에 NaN 값이 자리하고 있는 자리에 경도/위도 데이터를 삽입하여 작업을 완료한다.

 

작업의 진행을 확인할 수 있게하기위해 별도의 출력문을 만들어놨는데, 중요한 부분은 아니다.

그냥 이런식으로 현재 검색하고 있는 주소를 출력해주는 역할만 한다.

스킵해도 무관하니 편의에 따라 하면 된다.

 

위의 과정을 모두 수행하면

비어있던 위도 경도 데이터 셀이 모두 차있음을 알 수 있다.

 

아래는 깃허브에 업로드 되어있는 전체 코드이다.

 

GitHub - SCUTUM98/Ruas_Factory

Contribute to SCUTUM98/Ruas_Factory development by creating an account on GitHub.

github.com

 

728x90

'연습장 > Open API' 카테고리의 다른 글

[Kakao] Open API 사용 준비  (0) 2023.06.25

댓글