파이썬으로 지역 검색 및 지도에 나타내기 – 3. 지역 검색

안녕하세요. 언제나휴일의 언휴예요.

이번 작업은 Kakao 개발자센터의 지역 검색 서비스 사용입니다.

이번 작업은 파이썬으로 코드를 작성할 것이며 콘솔에서 검색어를 입력하면 결과(장소명, 경도, 위도)를 출력합니다.

다음은 실행한 결과 예입니다.

E:\Work\PyCh\QT_Pre\venv\Scripts\python.exe E:/Work/PyCh/KMap/Demo.py
지역 검색어:카카오
카카오 판교오피스(127.10820996551278,37.402054243658846)
카카오 스페이스닷원(126.57066132748933,33.450677320070916)
카카오 스페이스닷투(126.570875463183,33.4526219140826)
카카오프렌즈 판교점(127.108728343532,37.4020357477055)
카카오뱅크(127.108644810967,37.4012843732024)
카카오브이엑스(127.10158894465216,37.400122922772645)
카카오엔터테인먼트 판교오피스(127.108996408808,37.4007470412071)
카카오커머스(127.10680722042285,37.40046071226674)
카카오페이(127.110699049301,37.39426531392528)
카카오 고객센터(127.10736390272872,37.40275781100857)
카카오게임즈(127.11016618280905,37.39437843929819)
카카오모빌리티(127.1101250888609,37.39407843730005)
카카오엔터프라이즈(127.108636946335,37.4020952990786)
늘예솔카카오판교어린이집(127.108879816692,37.401345426449)
카카오브레인(127.10737294589218,37.402763208920256)

Process finished with exit code 0

카카오 개발자 센터에서 문서>로컬>개발 가이드를 선택하세요.

문서- 로컬 – 개발 가이드

로컬 개발 가이드에서 “키워드로 장소 검색하기”를 이용할게요.

로컬 개발가이드 – 키워드로 장소 검색하기

쿼리 문자열에 질의로 전달한 인자는 Request 항목을 보시면 나와있습니다.

필수 항목은 query, 나머지는 옵션입니다.

특이 사항은 쿼리 문자열과 함께 헤더로 인증 부분을 요구하고 있습니다.

“Authorization” 항목에 값으로 “KakaoAK {REST_API_KEY}”를 전달해야 합니다.

{REST_API_KEY} 부분은 내 애플리케이션에 발급받은 REST API 키를 의미합니다.

(*카카오 지도 API에서 사용하는 키는 JavaSript 키입니다.)

Request의 파라미터와 인증

Sample을 보면 쿼리 문자열을 사용하는 예를 확인할 수 있습니다.

사이트 주소: https://dapi.kakao.com/v2/local/search/keyword.json

필수 인자 : query

헤더: Authorization, KakaoAK {REST_API_KEY}

Sample에서는 y,x,radius를 인자로 전달하고 있지만 여기에서는 query를 제외한 나머지 인자는 사용하지 않을게요.

(여러분들은 다른 인자도 사용해 보세요.)

Request 예

응답 예를 보면 지역 정보는 documents에 있음을 알 수 있습니다.

documents의 각 항목이 하나의 지역 정보입니다.

하나의 지역 정보는 장소 ID, 장소명,…,경도(x), 위도(y) 등의 데이터를 제공합니다.

자세한 사항은 “카카오 개발자 센터 > 문서 > 로컬 >개발 가이드> 키워드로 장소 검색하기”의 Response 부분을 살펴보세요.

Response 예

1. Locale.py 구현

먼저 Locale 클래스를 정의합시다.

#Locale.py
import  json
class Locale:

JSON 결과에서 지역 정보가 있는 요소를 입력 인자로 받아 Locale 개체를 만드는 정적 메서드 MakeLocale을 구현합니다.

카카오 개발자 센터의 메뉴얼을 보면서 장소명(place_name), 위도(y), 경도(x) 부분을 얻어와서 Locale 개체를 만들어 반환합니다.

    @staticmethod
    def MakeLocale(post):
        try:
            pn = post['place_name']
            x = post['x']
            y = post['y']
            return Locale(pn,x,y)
        except:
            return None

생성자 메서드에서는 입력 인자로 장소명, 위도, 경도를 받아 멤버 필드에 설정합니다.

    def __init__(self,pn,x,y):
        self.pn = pn
        self.x = x
        self.y = y

다음은 Locale.py 전체 소스 코드입니다.

#Locale.py
import  json
class Locale:
    @staticmethod
    def MakeLocale(post):
        try:
            pn = post['place_name']
            x = post['x']
            y = post['y']
            return Locale(pn,x,y)
        except:
            return None
    def __init__(self,pn,x,y):
        self.pn = pn
        self.x = x
        self.y = y

2. LocaleSearcher.py 구현

이번에는 카카오 지역 검색을 이용하여 결과를 반환하는 부분을 구현합시다.

파일명은 LocaleSearcher.py 로 정할게요.

웹에 있는 문서 내용이나 서비스를 사용하기 위해 urllib.request가 필요합니다.

그리고 json 방식의 응답 결과를 쉽게 분석하기 위해 json 모듈도 사용할 거예요.

물론 앞에서 작성한 Locale 클래스를 사용해야겠죠.

#LocaleSearcher.py
import urllib.request
import json
from Locale import Locale

REST_API_KEY와 검색에 사용할 사이트 주소, 인증에 사용할 구문, 인증 헤더에 사용할 키를 변수로 선언할게요.

key ='내 애플리케이션이 발급받은 REST_API_KEY로 대체하세요.'
site='https://dapi.kakao.com/v2/local/search/keyword.json'
auth_key="KakaoAK "+ key
auth_header = "Authorization"

검색 질의를 입력 인자로 받는 SearchLocale 함수를 정의합시다.

def SearchLocale(query):

입력인자로 전달받은 질의를 utf-8로 변환할게요.

    query = urllib.parse.quote(query)

쿼리 문자열을 만듭시다. 여기에서는 “사이트주소?query={검색질의}”입니다.

    query_str = site+"?"+"query="+query

Request 개체를 생성합니다. Request 개체는 웹 서버에 쿼리 문자열과 헤더 등을 전달하여 결과 웹 페이지를 받는 역할을 수행합니다.

여기에서는 쿼리 문자열로 개체를 생성하고 인증 부분을 헤더로 추가합니다.

    request = urllib.request.Request(query_str)
    request.add_header(auth_header,auth_key)

이제 웹 서버에 요청합니다. 요청 결과를 response 변수로 받을게요.

    response = urllib.request.urlopen(request) #웹 서버에 요청

결과 코드가 200일 때 정상적인 코드입니다.

    rescode = response.getcode()
    if(rescode == 200):
        #to do
    else:
        return []

#to do 부분을 구현합시다.

먼저 response의 결과를 읽어와서 utf-8로 디코딩할게요.

        res = response.read().decode('utf-8')

utf-8로 디코드한 결과를 json 방식으로 로딩합니다.

        jres = json.loads(res)
        if jres == None:
            return []

결과 중에 장소들은 ‘documents’ 요소에 있습니다.

각 요소로 Locale 개체를 만들어 결과 컬렉션에 보관 후 반환합니다.

        for jloc in jres['documents']:
            locale = Locale.MakeLocale(jloc)
            if(locale!=None):
                locales.append(locale)
        return locales

다음은 LocaleSearcher.py 파일의 전체 소스 코드입니다.

#LocaleSearcher.py
import urllib.request
import json
from Locale import Locale

key ='내 애플리케이션의 REST API 키'
site='https://dapi.kakao.com/v2/local/search/keyword.json'
auth_key="KakaoAK "+ key
auth_header = "Authorization"

def SearchLocale(query):
    query = urllib.parse.quote(query)
    query_str = site+"?"+"query="+query
    request = urllib.request.Request(query_str)
    request.add_header(auth_header,auth_key)
    response = urllib.request.urlopen(request) #웹 서버에 요청
    rescode = response.getcode()
    if(rescode == 200):
        res = response.read().decode('utf-8')
        jres = json.loads(res)
        if jres == None:
            return []
        locales =[]
        for jloc in jres['documents']:
            locale = Locale.MakeLocale(jloc)
            if(locale!=None):
                locales.append(locale)
        return locales
    else:
        return []

3. 테스트 코드 작성하기

이제 작성한 것을 테스트하기 위해 Demo.py파일을 추가하여 다음과 같이 작성합니다.

import LocaleSearcher
from LocaleSearcher import  *
query = input("지역 검색어:")
locales = SearchLocale(query)
for locale in locales:
    print("{0}({1},{2})".format(locale.pn,locale.x,locale.y))

Demo.py를 실행하여 테스트를 해 보세요.

이것으로 이번 작업을 마칠게요.