간호사 업무 해소 환자 위치 찾기 프로젝트 (2. 공공데이터 활용 )
1. 개요
사용자가 병원의 이름을 입력 했을 때, 해당 키워드가 포함된 병원의 리스트와 병원의 위치 데이터를 활용하고 싶었다.
2. 공공데이터 이용하기
이용하려고 하는 공공데이터에는 약 78000개의 병원 데이터가 있었다. 이 병원들 중 사용자가 입력한 키워드가 병원 이름에 포함되어 있는 경우에, 배열에 저장하고 list로 나타내는 script를 작성했다.
$.ajax({
type:'GET',
dataType:'JSON',
url:`${apiUrl}?ServiceKey=${serviceKey}&numOfRows=${numOfRows}&pageNo=1&sidoCd=${cityData}`,
error: function(err){
console.log(err);
},
success: function(data){
console.log(data);
var items = data.response.body.items.item;
console.log(items[0].yadmNm)
for (let i = 0; i < items.length; i++){
if (items[i].yadmNm.includes(hospital)){
hosLi += "<li class='hospitalName' data-x='"+items[i].XPos+"' data-y='"+items[i].YPos+"' data-key='"+items[i].yadmNm+"'>"+items[i].yadmNm+" : "+items[i].addr+"</li>"
}
}
$("#hospitalList").html(hosLi);
// li에 이벤트 부여하기
$(document).on("click",".hospitalName",hospitalClick);
}
})
- 위의 코드는 공공 데이터를 JSON 타입으로 받아오고, .includes() 함수를 사용해서 사용자가 입력한 키워드가 포함된 병원만 li로 만들어서 나타내도록 검색 기능을 구현했다.
보통 대량의 정보를 가져오는 공공데이터는 한 번에 가져올 수 있는 데이터의 양에 한도가 있기 때문에
78000개의 병원 데이터를 모두 가져와서 키워드와 비교할 때는 100개 정도의 rows 를 780개의 page로 나눠서 불러오는 작업을 수행해야한다.
하지만 이 작업을 매번 수행하면 시간이 너무 오래걸린다. 그래서 병원 수가 1500개 정도 되는 울산으로만 한정해서 이번 과제를 수행했다.
공공데이터를 일정 주기마다 JSON형태로 저장하는 python파일을 만들고, JSON으로 미리 저장되있는 데이터를 활용하는 방법이 더 좋다. 다음에 대량의 공공데이터를 이용할 필요가 있다면 이 방법을 시도해 보자.
3. python 파일 예시
: 이 코드는 공공데이터를 30개 씩 약 2500개의 page로 불러오고 필요한 데이터를 JSON형태로 변환한 후
DB에 저장하는 코드이다. 하지만 이 방법은 시간이 너무 오래 걸리고 DB에 접속할 때도 무거워질 것을 고려해서 실행하지는 않았다.
다음번에는 이런 방식으로 데이터를 불러와서, json 형태의 파일로 저장해서 활용할 수 있도록 하자.
또한 json형태로 저장한 파일을 공공데이터가 갱신되는 주기에 맞춰서 자동으로 갱신되는 기능도 만들어보자.
import requests
import xml.etree.ElementTree as ET
import mysql.connector
# MySQL 연결 정보
MYSQL_HOST = '192.168.30.13'
MYSQL_PORT = 3306
MYSQL_USER = 'jht0725'
MYSQL_PASSWORD = '1234'
MYSQL_DB = 'mydb'
# API 호출 및 데이터 수신
url = 'https://apis.data.go.kr/B551182/hospInfoServicev2/getHospBasisList'
service_key = ''
params = {
'ServiceKey': service_key,
'numOfRows': 30
}
total_data = []
page = 1
while len(total_data) < 76642:
params['pageNo'] = page
response = requests.get(url, params=params)
print(response)
# XML 형식의 응답을 파싱하여 데이터 추출
root = ET.fromstring(response.content)
print(root)
items = root.findall('.//item')
print(items)
for item in items:
# 필요한 데이터 추출
hospital_name = item.findtext('yadmNm')
sido_cd_nm = item.findtext('sidoCdNm')
telno = item.findtext('telno')
x = item.findtext('XPos')
y = item.findtext('YPos')
address = item.findtext('addr')
if x is not None:
x = float(x)
else:
x = 0.0
if y is not None:
y = float(y)
else:
y = 0.0
print('hospital_name: {}, sido_cd_nm: {}, telno: {}, x: {}, y: {}, address: {}'.format(hospital_name, sido_cd_nm, telno, x, y, address))
total_data.append({'hospital_name': hospital_name, 'sido_cd_nm': sido_cd_nm, 'telno': telno, 'x': x, 'y': y, 'address': address})
page += 1
# MySQL에 데이터 저장
conn = mysql.connector.connect(
host=MYSQL_HOST,
port=MYSQL_PORT,
user=MYSQL_USER,
password=MYSQL_PASSWORD,
database=MYSQL_DB
)
cursor = conn.cursor()
for data in total_data:
hospital_name = data['hospital_name']
sido_cd_nm = data['sido_cd_nm']
telno = data['telno']
x = data['x']
y = data['y']
address = data['address']
# INSERT 쿼리 실행
query = "INSERT INTO hospital (hospitalName, sidoCdNm, telno, X, y, addr) VALUES (%s, %s, %s, %s, %s, %s)"
values = (hospital_name, sido_cd_nm, telno, x, y, address)
cursor.execute(query, values)
conn.commit()
conn.close()
4. 결과
'피부' 를 검색하면 울산에 있는 병원들 중 이름에 피부가 들어가는 병원들을 확인할 수 있다.