복수의 출발지,도착지를 네이버 길찾기api를 활용해 최단거리 찾기

전윤환·2022년 5월 9일
0

파이썬 삽질하기

목록 보기
4/4

작성일자: 2022/05/09
알게된것: requests를 사용한 코딩은 selenium을 사용한 코딩보다 처리속도가 너무너무 빠르다. 원리를 어설프게나마 이해한 나 칭찬해
추후방향: 판다스랑 오픈파이엑셀로 출발/도착지 리스트를 불러와서 변수에 담아서 함수 실행하기, 결과값을 엑셀에 넣어서 저장하기

들어가며

내일 출근이다! 원래 퇴사였는데 출근하게 됐다! 회사에서 좋은 조건을 제시해주긴 했지만 원래 쉬는 날인데 출근을 한다니 너무 슬프다 ㅠㅠㅠ 이것만 얼른 쓰고 자야지...

로직 구상

  1. 복수의 출발지를 [{}, {}, {}] 이런 제이슨 형태로 만든다.
  2. 복수의 목적지도 같은 형태로 만든다.
  3. 출발지 1개당 목적지 전체를 각각 매칭해서 길찾기를 돌린다.
  4. 그 중 거리가 가장 가까운 목적지에 대한 정보를 꺼낸다.

코드 작성

import json
import requests




m1_list = [
  {
    '매장명': '',
    '매장주소': '',
    'x': '', 'y': ''
  },
  {
    '매장명': '',
    '매장주소': '',
    'x': '', 'y': ''
  },
  {
    '매장명': '',
    '매장주소': '',
    'x': '', 'y': ''
  },
  {
    '매장명': '',
    '매장주소': '',
    'x': '', 'y': ''
  }
  
]

# 2-3. 센터별 좌표
centers = [
    {'센터명': '', '센터주소': '',
    'x': '', 'y': ''},
    {'센터명': '', '센터주소': '',
    'x': '', 'y': ''},
    {'센터명': '', '센터주소': '',
    'x': '', 'y': ''},
    {'센터명': '', '센터주소': '',
    'x': '', 'y': ''},
    {'센터명': '', '센터주소': '',
    'x': '', 'y': ''},
   ]

# 3. directions5를 이용해서 각 센터별 거리, 시간, 비용(톨비, 기름값) 추가

# 네이버 클라우드 Direction 5 아이디, 비밀번호
dir_client_id = '따옴표 안에 아이디 입력'
dir_client_secret = '따옴표 안에 시크릿 입력'

url = f'https://naveropenapi.apigw.ntruss.com/map-direction/v1/driving'

start = ''
goal =  ''
cartype = ''
fueltype = ''
mileage = ''
headers = {'X-NCP-APIGW-API-KEY-ID':dir_client_id, 'X-NCP-APIGW-API-KEY': dir_client_secret}

def pathfind(start, goal):
    param = {'start': start, 'goal': goal}
    request = requests.get(url, param, headers=headers)
    if request.status_code == 200:
        result = dict(request.json())
        if result['code'] == 0:
          거리 = result['route']['traoptimal'][0]['summary']['distance'] #미터
          시간 = result['route']['traoptimal'][0]['summary']['duration'] #천분의일초
          톨비 = result['route']['traoptimal'][0]['summary']['tollFare']
          기름 = result['route']['traoptimal'][0]['summary']['fuelPrice']
          global paths
          paths = {'거리': 거리, '시간': 시간, '톨비': 톨비, '기름': 기름}
        #   print(거리, 시간, 톨비, 기름) # 잘 작동됨
        else: print('에러', result['message'])
    else: print('에러', request.status_code)

for i in range(len(m1_list)):
    m_x = m1_list[i]['x']
    m_y = m1_list[i]['y']
    start = f'{m_x},{m_y}'
    goallist = []
    for ii in range(len(centers)):
        c_x = centers[ii]['x']
        c_y = centers[ii]['y']
        goal = f'{c_x},{c_y}'
        pathfind(start, goal)
        center = centers[ii]['센터명']
        paths['센터명'] = center
        goallist.append(paths)
        # goallist = [{거리: x, 시간: y, 톨비: z, 기름: xx, 센터명: yy}, {거리: x, 시간: y, 톨비: z, 기름: xx, 센터명: yyy}, ...]
        nearst_dis = goallist[0]
        for iii in range(len(goallist)):
            if goallist[iii]['거리'] < nearst_dis['거리']:
                nearst_dis = goallist[iii]
            else: pass
        nearst_dis['매장명'] = m1_list[i]['매장명']
    print(nearst_dis)
  

간략한 설명

코드의 대략적인 사항은 전 글에서 다뤘으니 넘어간다.

출발지 = m1_list
도착지 = centers

출발지는 전국의 맘스터치 매장 중 아무거나 몇개를 골랐고, 도착지는 우리회사 센터 중 몇개를 꺼냈다.

for문을 통해 출발지 1개 vs 도착지 n개를 돌렸고, 그 결과값 중 거리, 시간, 톨비, 기름값을 goallist라는 리스트에 딕셔너리 형태로 하나씩 담았다.

한번 더 반복문을 돌려서 goallist의 거리값을 하나씩 꺼내서 비교해보고, 가장 작은 거리가 있는 딕셔너리를 nearst_dis라는 변수에 딕셔너리 형태로 담았다.

그 후, 첫번째 반복문 즉, n개의 도착지를 돌리는 변수 i를 가져와서 매장명을 최종딕셔너리에 추가했다.

확실히..api를 사용하니 결과값 출력되는 속도가 넘사로 빠르다.
'난 셀레니움밖에 안해봤으니까 셀레니움으로만 코드짤거야' 라고 생각하고 하던거 계속 했으면 눈물났을거다. 우연하게도 requests를 이해하게 돼서 너무나 행운이다.

profile
코딩 연습장. 발전하고 싶습니다. 모든 방향에서의 비판 부탁드립니다.

4개의 댓글

comment-user-thumbnail
2022년 7월 28일

안녕하세요 좋은글 정말 감사합니다. 윗 글에 대한 질문이 하나 있는데요.
글에선 json으로 지명과 좌표값을 입력하고 있는데 csv파일을 json으로 변경하지 않고 적용해서 대량의 주소를 일괄적으로 조회하려면 어떻게 해야할지 알려주실수 있으실까요?

혹, csv 파일을 json으로 변경해야한다면 어떻게 적용해야할까요?

1개의 답글
comment-user-thumbnail
2022년 8월 9일

답글 정말 감사합니다. 아래 대댓을 달려고했으나 입력되지않아 새로 댓글을 남깁니다.

답변해주신덕에 해당 문제를 잘 해결할 수 있었습니다. 정말 감사드립니다. 추가로 질문을 하려하는데 괜찮을런지요.
해당 코드에서 option인 fueltype이나 mileage를 원하는 값으로 지정하려면 어떻게 해야할 까요? 항상 갑사드립니다..ㅎㅎ

1개의 답글