국립중앙의료원 의 전국 응급실 정보를 크롤링한다.
# 필요한 모듈 import
import requests as req
import pandas as pd
from bs4 import BeautifulSoup as BS
import json
# 전국 응급실 정보 크롤링
hospital_list = []
temp_dict = {}
for page in range(1, 39):
url = f'https://www.nmc.or.kr/nmc/emrrm/emrrm/nearEmrrmList.do?menuNo=200323&cdVal1=a013&cdVal2=&pageIndex={page}'
res = req.get(url)
soup = BS(res.text, "html.parser")
a_tag = soup.select("a[data-clipboard-text]")
for hospital in a_tag:
hospital_data = hospital["data-clipboard-text"]
temp_dict['name'] = hospital_data.split('/')[0].strip()
temp_dict['phone'] = hospital_data.split('/')[1].strip()
temp_dict['address'] = hospital_data.split('/')[2].split('(')[0].strip()
if temp_dict['name'] != 'https:':
hospital_list.append(temp_dict)
temp_dict = {}
else:
temp_dict = {}
# to json dump
with open('hospital_data.json', 'w', encoding='utf-8') as f:
f.write(json.dumps(hospital_list, ensure_ascii = False, indent = 4))
# 필요 모듈 import
import numpy as np
import pandas as pd
import folium
from folium import Choropleth
from folium import plugins
from folium import Marker
from folium.plugins import MarkerCluster
import googlemaps
import json
from math import sin, cos, sqrt, atan2
# 불필요한 경고문 제거
import warnings
warnings.filterwarnings('ignore')
# 구글맵 활용을 위한 key 지정
gmap_key = "yourkey"
gmaps = googlemaps.Client(key=gmap_key)
# json 불러오기 및 DataFrame 생성
geo_path = open('hospital_data.json', encoding='UTF8')
geo_data = json.load(geo_path)
df = pd.DataFrame(geo_data)
# 지도 생성
korea_map = folium.Map(zoom_start=7, location=[37.5502, 126.982])
# 주소를 위도, 경도로 변경
lat = []
lng = []
for index in df.index:
try:
address = geo_data[index]['address']
geo = gmaps.geocode(address)[0]['geometry']['location']
lat.append(geo['lat'])
lng.append(geo['lng'])
except:
lat.append(np.nan)
lng.append(np.nan)
# DataFrame에 새로운 컬럼 생성후 value 지정
df['lat'] = lat
df['lng'] = lng
# 결측치 확인
df[df['lng'].isnull()]
df[df['lat'].isnull()]
# 결측치 수정 >> 병원 한곳만 주소가 적용이 안돼 하드코딩으로 데이타 프레임에 주소 넣어줌
# 좌표찾기 : https://coordinates-gps.gosur.com/ko/
df.loc[102, 'lng'] = 127.2623
df.loc[102, 'lat'] = 36.4796
# 병원 위치 지도에 마커
for index, data in enumerate(df.index):
Marker(location = [df.iloc[index]['lat'],df.iloc[index]['lng']],
popup=df.iloc[index]['name'],
icon=folium.Icon(color='red',icon='star')
).add_to(korea_map)
마커가너무 많아 지도가 지저분해 보여 MakerCluster로 정리해주고자 함
# 지도 초기화
korea_map = folium.Map(zoom_start=7, location=[37.5502, 126.982])
# 마커 클러스터 생성
mc = MarkerCluster()
# 마커 클러스터를 활용해 지도에 마커 생성
for index, data in enumerate(df.index):
mc.add_child(
Marker(location = [df.iloc[index]['lat'],df.iloc[index]['lng']],
popup=df.iloc[index]['name'],
icon=folium.Icon(color='red',icon='star')
)
)
korea_map.add_child(mc)
# 현재 위치 = 서울역
current_lat = 37.5562
current_lng = 126.9723
# 가장 가까운 장소의 인덱스
# 가장 먼 거리 값을 저장하기 위해 최대값(inf)으로 설정
nearest_index = None
nearest_distance = float('inf')
# 모든 마킹 장소와의 거리를 계산
for index, data in enumerate(df.index):
lat = df.iloc[index]['lat']
lng = df.iloc[index]['lng']
# 두 지점 사이의 거리를 계산
# 참고 : https://stackoverflow.com/questions/19412462/getting-distance-between-two-points-based-on-latitude-longitude
dlat = lat - current_lat
dlng = lng - current_lng
a = sin(dlat / 2)**2 + cos(current_lat) * cos(lat) * sin(dlng / 2)**2
c = 2 * atan2(sqrt(a), sqrt(1 - a))
distance = 6371 * c
# 가장 가까운 장소인지 확인
if distance < nearest_distance:
nearest_index = index
nearest_distance = distance
if nearest_index is not None:
print("The Nearest Hospital is:")
print("Index:", nearest_index)
print("Name:", df.iloc[nearest_index]['name'])
print("Phone:", df.iloc[nearest_index]['phone'])
print("Address:", df.iloc[nearest_index]['address'])
print("Latitude:", df.iloc[nearest_index]['lat'])
print("Longitude:", df.iloc[nearest_index]['lng'])
else:
print("No location found.")
# 출력
The Nearest Hospital is:
Index: 110
Name: 서울적십자병원
Phone: 02-2002-8000
Address: 서울특별시 종로구 새문안로 9, 적십자병원
Latitude: 37.5671402
Longitude: 126.9670566
# 위에서 뽑은 가장 가까운 병원과 내 위치와의 직선 경로
# 경로 표시
folium.PolyLine(
locations=[(current_lat, current_lng), (df.iloc[nearest_index]['lat'], df.iloc[nearest_index]['lng'])],
color='red',
weight=2.5,
opacity=1
).add_to(korea_map)
# 마커 표시
folium.Marker(
location=[current_lat, current_lng],
popup='Starting Point'
).add_to(korea_map)
folium.Marker(
location=[df.iloc[nearest_index]['lat'], df.iloc[nearest_index]['lng']],
popup='Nearest Place'
).add_to(korea_map)