공부공간

ToyProject ) 내 주변 약국에는 마스크가 얼마나 남아있을까..? 본문

Natural Language Processing/Crawling

ToyProject ) 내 주변 약국에는 마스크가 얼마나 남아있을까..?

개발자가될수있을까? 2020. 3. 16. 00:15

 

코로나가 기승을 부리고있다.. 사실 무엇보다도 예방하는게 가장 중요하다..

 

마스크를 확보하는것이 중요하지만, 사실상 어느약국에 얼만큼 마스크가 남아있는지 알수가 없다.

 

공공데이터 api를 이용해서 주소를 기반으로 내주변 약국에 마스크가 있는지? 없는지? 얼마나있는지?

 

알려주는 기능을 한번 개발해보았다. ( 마크스 5부제를 통해서 출발하기전에 확인하면 좋을것같다 )

 


예전에 음성합성프로젝트를 같이한

  https://somjang.tistory.com/

 

솜씨좋은장씨

 

somjang.tistory.com

이 folium이라는 좋은 파이썬 라이브러리를 소개시켜줬고, 한번 써볼겸 + 요즘 알고리즘만 하다보니 이런 문제정의와

 

구현하는데 어색해지기때문에..  구현시간은 30분정도 걸렸다.

 


Code

개발환경 : google colab ( only cpu ) , python 3.x


!pip install pandas_profiling
!pip install folium
!pip install pprint
#필요한 라이브러리 다운

ㅇ 시작하기에 앞서 간단한 라이브러리를 설치해주자 

데이터프레임을 분석해주는 판다스프로파일링

지도에 마크를 찍어주고 지도를 표시해주는 폴리움

출력을 예쁘게해주는 피프린트 ( 안써도된다 ) 


import folium
from folium.plugins import MarkerCluster , MiniMap
import requests ,json ,pprint
from urllib import parse
from tqdm import trange

Url = "https://8oi9s0nnth.apigw.ntruss.com/corona19-masks/v1/storesByAddr/json?Address="
Address ="서울특별시 강남구 역삼동"
Url +=parse.quote(Address)
## 주소는 string 입력을 받는식으로 처리할예정
## Url에 Enconding을 해주고 붙여주어서 현재 주소에대한 요청을 서버에 날린다!
re = requests.get(Url)
json = re.json()


pp = pprint.PrettyPrinter(indent=4)
pp.pprint(json)
## pprint로 예쁘게 출력해주자
## 총 460개 ( missing value 포함 )의 약국에대한 경도,위도,이름,판매시간, 주소 등의 정보를 받았고 이를 json으로 관리한다.

Url에 get방식으로 요청을 날리는 것을 간단하게 파싱을 해보았다. 

 

corona19-masks/v1/ 까지는 공통된 url이고 각각에 기능에 따라서 뒤에 붙는 값들이 달라진다.

 

나는 주소를 기준으로 요청을 할 것이기에 storesByAddr을 선택하였고 뒤에는 주솟값을 인코딩한 값이 전달된다.

 

감이 안온다면, 

 

https://app.swaggerhub.com/apis-docs/Promptech/public-mask-info/20200307-oas3

 

Build, Collaborate & Integrate APIs | SwaggerHub

 

app.swaggerhub.com

위 사이트에서 한번 예시로 날려보는 것을 추천한다.

 

서울특별시 강남구 역삼동에대한 요청 URL은

https://8oi9s0nnth.apigw.ntruss.com/corona19-masks/v1/storesByAddr/json?address=%EC%84%9C%EC%9A%B8%ED%8A%B9%EB%B3%84%EC%8B%9C%20%EA%B0%95%EB%82%A8%EA%B5%AC%20%EC%97%AD%EC%82%BC%EB%8F%99  

이고 주솟값이 인코딩되어서 들어간것을 알 수있다.

 

 

강남구에 위치한 약국들의 정보를 받아왔다!

 


import pandas as pd
import pandas_profiling as pp

df = pd.DataFrame(json['stores'])
pp.ProfileReport(df)

 우리들이 궁금한 정보들은 stores라는 key로 이루어진 value들이므로 이들만 데이터프레임에 저장하여 관리하자.

결측치와 상관관계등의 정보를 파악하기위해 판다스 프로파일러를이용하여 출력을해보자.

 

다른정보도 중요하지만 460개중에 21개의 결측치가 포함된것을 확인하였다, na값이거나 뭔가 이상한값이거나 등등..

그렇다면, 결측치를 포함한 행을 제거하고 진행을 해보자.

df = df.dropna()

위 데이터프레임에는 결측치가 제거되었으므로 위의 데이터로 나머지 작업을 진행하자


color =  {
   'plenty' : 'green' , 'some' : 'blue' , 'few' : 'red' ,'empty' : 'gray' , 'break' : 'black' ,
}

korea = {
    'plenty':'100개 이상', 'some':'30개 이상', "few":'2개이상 30개 미만', 'break' : "영업 중지" , "empty":"재고 없음"
}

이후에 간단한 마커들에 들어갈 속성을 지정해주자.

 

100개 이상이면 : green 으로

30개이상이면 : blue

2개이상이면 : red

구매할수없다면, black과 gray로 색상을 지정해주었다.

 



maskmap = folium.Map ((37.5642135,127.0016985) , zoom_start=15)
marker = MarkerCluster()

name = list(df['name'])
lat = list(df['lat'])
lon = list(df['lng'])
remain = list(df['remain_stat'])

for i in trange(len(name)):
    marker.add_child(folium.Marker(location=[lat[i], lon[i]] , icon = folium.Icon(color=color[remain[i]]  ) , popup=name[i]+ korea[remain[i]]))
    maskmap.add_child(marker)
        
maskmap.save('mask.html')
maskmap

간단하게 folium 사용법을 알아보자. 먼저 Map함수에 시작 경도,위도를 튜플형식으로 넣어주고

처음에 zoom을 어느정도로 시작할 것인지 정수값을 넣어준다.

 

이후에 생성된 map에 marker 객체를 찍을 것인데, marker객체에 속성값을 달리하므로

( 색상, 이름, 경도, 위도 ) 매번 map에 다른 마커들이 찍히게된다. 

 

위 작업을 전체 df의 길의만큼 반복하고 완료된다면 maskmap을 저장해주자.

 

이후에 ,

 

maskmap을 찍어보면?


이런식으로 강남구 약국에대한 마스크정보가 찍히게된다.


사실 나는 내가 구매하려고 만든것이기에 우리집근처로가보았다.

 

교육받는곳근처에 2개이상의 소량이 남아있었다.. 내일가봐야겠다..


사실애초에 구매가능한경우만 찍어볼수도있다. 마커를 찍기 전에 ,

 

 if(remain[i] in ['few' , 'plenty' , 'some']):

 

한줄을 추가해주었다. 즉 2개이상이 남아있다면 ( 구매할 수 있다면 ) marker를 생성하여 찍어주는 작업이다.

 

maskmap = folium.Map ((37.5642135,127.0016985) , zoom_start=15)
marker = MarkerCluster()

name = list(df['name'])
lat = list(df['lat'])
lon = list(df['lng'])
remain = list(df['remain_stat'])

for i in trange(len(name)):
  if(remain[i] in ['few' , 'plenty' , 'some']):
    marker.add_child(folium.Marker(location=[lat[i], lon[i]] , icon = folium.Icon(color=color[remain[i]]  ) , popup=name[i]+ korea[remain[i]]))
    maskmap.add_child(marker)
        
maskmap.save('.mask.html')
maskmap

 


집근처에 두곳이있지만 상당히 극소량이 남아있는것을 확인했다.


 

직접가보지않고 마스크의 수량을 알수있어서 편리하기하지만.. 가는도중팔리면..?

 

maskmap.save('.mask.html')

또한 폴리움에서 html로 저장할수있는 기능도 제공한다. 위 기능으로 저장한다면 현재경로에 저장이된다. 

 

 

 

 


다음에는 Dialogflow를이용해서 주기적으로 marker를 생성하고

 

사용자가 설정한 양 이상이 존재하면 카카오톡으로 알려주는 기능을 개발할 예정이다.

 

*** 모두들 코로나조심하세요 ***

Comments