ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 파이썬에서 주소 다루기
    Python/이것저것 파이썬 2021. 12. 12. 01:03
    반응형

    1만 6천 개의 장소(주소)와 
    주민등록인구의 비율을 찾는
    비교적 간단한 프로젝트를 최근 진행했다. 

    간단하게 요약해 보겠다. 

    앞으로도 주기적으로 추적 조사해야 하기 때문에
    최대한 자동화 하려고 노력했...

    1.  법정동 VS 행정동

    1) 인구는 행정동 기준

    주민등록인구는 행정안전부에서 찾을 수 있었고...
    https://jumin.mois.go.kr/

    행정동 기준으로 정리되어 있었다. 

    2) 원 데이터(주소)는 법정동 기준

    동에는 법정동과 행정동이 있는데,
    행정동은 주민자치센터(동사무소)를 기준으로 하는 동이고,
    법정동은 서류, 주소에 사용되는 동이다. 
    https://www.yna.co.kr/view/AKR20180521134900061

    법정동은 인구가 없는 곳까지 정의되어 있으니...
    인구는 행정동 기준으로 정리되어 있을 것이라 예상했었는데...

    문제는 생각보다 법정동과 행정동이 일치하지 않는 경우가 많았다. 
    법정동과 행정동이 일치하는 동네에서만 살아와서 이건 잘 몰랐던 것.

    기존 주소에서 행정동을 찾아야 하는 골칫거리가....

    대부분의 통계 작업에서
    raw 데이터의 전처리 과정이
    결과를 뽑는 과정보다 힘들다.. 

     

    2. 다음 카카오의 로컬 API

    처음에는 주소 데이터를 받아서
    직접 처리할까 생각했는데 

    https://www.juso.go.kr/addrlink/jusoSearchSolutionIntroduce.do

    점점 산으로 가는 느낌이 들어서...
    거인의 어깨에 올라타자로 작전 변경... 
    '다음'의 '로컬 API' 덕분에 쉽게 일을 처리할 수 있었다. 

    땡큐 다음, 카카오.. ~!

     

    다음의 주소 관련 API는 2가지가 있는데... 

    첫 번째가 우편번호 서비스..

    https://postcode.map.daum.net/guide

     

    두 번째가 로컬(Local) API이다. 

    원래는 지번 주소나, 도로명 주소를 보내면 좌표(지도 표기용)를 돌려주는 API인데..
    좌표뿐만 아니라, 지번 주소, 도로명 주소, 좌표, 우편번호, 빌딩명 등을 함께 제공한다. 
    행정동과 법정동까지 ㄷㄷㄷ

    https://developers.kakao.com/docs/latest/ko/local/dev-guide

     

    나는 이 두 번째 API를 사용해서 쉽게 데이터를 찾을 수 있었다. 

     

    3. 다음 로컬 API로 찾을 수 없는 주소들... 

    1) 군시설

    군사 시설의 주소는 좌표가 안 나오더란...

    아마 예전의 흑역사의 영향이 아닌가...
    https://imnews.imbc.com/replay/2021/nw1400/article/6059099_34915.html

    네이버 지도에선 검색이 되니... 

     

    2) 건물명, 층, 호수 등이 병기된 경우

    원 데이터의 주소에는
    건물명, 층, 호수 등이 병기된 경우가 많았는데,
    다음의 API는 조금 예민해서
    이런 경우 제대로 찾지 못하는 경우가 있었다. 

    100여 개 정도.

    정규식을 이용해서 주소 부분만 남기는 전처리를 했고... 

     

    3) 3·15 대로

    '경상남도 창원시 마산합포구 3·15대로' 및 유사한 몇몇 사례 덕분에
    파이썬 코드도 추가되었다. ㅠ,.ㅠ 

    잊지않겠다. 3·15대로!!

     

    4. 네이버 로컬 검색 API

    이런 과정을 거쳐도 검색이 안 된 주소는 네이버를 이용했다. 

    네이버에서는 주소 검색은 없었으나,
    원 데이터가 상호 + 주소 데이터였던 관계로,
    네이버의 로컬 검색 API를 이용해 주소를 찾을 수 있었다.

    네이버의 로컬 검색 API는
    '동네 가게 검색' 등에 사용할 수 있는 API로
    도로명 주소, 지번 주소, 좌표 등을 제공한다. 
    https://developers.naver.com/docs/serviceapi/search/local/local.md

    네이버의 로컬 검색 API는 덜 예민하다. 
    'xx구 xx동 xx분식'으로 검색이 된다.  

    네이버로 '정제된' 주소를 찾은 뒤,
    다시 다음의 API를 이용해서 행정동을 찾았다.

     

    5. 수동 처리 

    30여 개 정도가 남았고,
    이것은 수동으로 처리했다..

    수동으로 처리한 데이터는
    DB에 별도 테이블로 저장해
    다음에는 자동으로 처리되도록 했다. 

     

    6. 최종 확인

    마지막으로 최종 도로명 주소가
    원 데이터의 도로명 주소에 포함되는 지를 확인했다.

    최종 도로명 주소 : 'xx시 xx구 xx로 123'
    원 주소 : 'xx시 xx구 xx로 123 B2~6,8~9층 (xx동, xx빌딩)'

    네이버 로컬 검색에 xx구 xx 분식을 검색하면, 
    다른 구에 있는 비슷한 상호의 분식점이 나올 수 있기 때문에 
    이런 절차를 넣었다.  

    일치하지 않는 데이터는
    6~70여 개 정도였다.  

    원 데이터가 오래된 주소라
    면이 읍으로 바뀌었는데
    데이터엔 반영되지 않았던 것이
    대부분이었다.

    이들도 별도의 테이블을 만들어
    따로 관리하도록 했다.  

    실제로 수정이 필요한 사례는
    5개 정도였다.

    생각보다 할만한 작업이었다. 

     

    * 다음 API 코드

    import requests
    
    headers = {"Authorization": "KakaoAK **REST_API_KEY**"}
    
    
    def get_address(address):
        url = f'https://dapi.kakao.com/v2/local/search/address.json?query={address}'
        h_name = ''
        try:
            h_name = requests.get(url, headers=headers).json()[
                'documents'][0]['address']['region_3depth_h_name']
        except Exception as e:
            print(e)
            print(address)
        return h_name

    좀 더 격식을 차린 스타일인가... 

    import requests
    
    
    headers = {"Authorization": "KakaoAK **REST_API_KEY**"}
    
    
    def get_address(address):
        params = {'query': address}
        url = 'https://dapi.kakao.com/v2/local/search/address.json'
        h_name = ''
        try:
            json_data = requests.get(url, headers=headers, params=params).json()
            h_name = json_data['documents'][0]['address']['region_3depth_h_name']
        except Exception as e:
            print(e)
            print(address)
        return h_name
    반응형
Designed by Tistory.