데이터를 기반으로

공공데이터 포털 약국 현황 API 본문

데이터 수집/API

공공데이터 포털 약국 현황 API

이노후 2020. 8. 2. 02:06
728x90
반응형

안녕하세요~~



오늘은 공공 데이터 포털에 올라와 있는 심평원 약국 현황 데이터를 받아오려고 합니다!!


저번에 올렸던 글은 T-map API 였는데요!!


그건 Json으로 받아왔지만 이번 건 XML 형식으로 받아오는 걸로 진행해보고자 해요!!


그리고 그땐 그냥 print로 제가 원하는 값 추출해서 보는 게 다 였지만!! 이번 건은 필요데이터를 받아 엑셀로 저장하는 것 까지 해볼 생각입니다!!!!


크게 어렵지 않아요!! ㅎㅎ 자! 그럼 먼저 공공데이터 포털에 들어가서 확인을 해봐야겠죠?



https://www.data.go.kr/data/15001673/openapi.do

위 주소는 공공데이터 포털의 전국 약국 현황 조회 서비스 Open API 제공 사이트 입니다!!


페이지에 가셔서 가장 먼저 해야할 것은 참고문서를 다운 받아 주세요!!!!


API에 요청 값과 응답 값을 볼 수 있기에 꼭 필요한 과정이에요!!


문서에는 요청 및 응답 관련한 것도 볼 수 있지만 데이터들이 어떻게 구성되어 있는지 그리고 필수 값이 무엇인지 확인할 수 있습니다!!


간혹 꼭 필요한 데이터인데 필수 값이 아니라면 null로 나오는 값들이 있기에 사전에 확인이 꼭 필요합니다!



회원가입 후 키를 발급 받으시고~




다운 받은 문서나 사이트에서 확인해보시면 요청변수가 굉장히 많습니다!!


하지만, 요청 변수를 꼭 다 입력해야하는 것은 아닙니다!!


저는 모든 정보를 갖고 올 것이기 때문에!!! 


페이지 번호랑 한페이지 결과 수 만 요청변수에 집어 넣었습니다!!!


그렇게 생성된 URL은 아래와 같습니다!!


http://apis.data.go.kr/B551182/pharmacyInfoService/getParmacyBasisList?ServiceKey=이곳은서비스키 넣는 곳&pageNo=1&numOfRows=20


한 페이지 결과수가 의미하는 것은 한 페이지당 몇개 씩 보여줄 거냐를 의미합니다!!


너무 많으면 또 보이지가 않거나 페이지를 불러오는 데 시간이 너무 오래 걸립니다!!


그래서 적당한 row수를 정해서 지정해주면 됩니다!!


그래서 저는 한 페이지 당 20개의 로우를 가져올 것이고 페이지 넘버를 for문을 돌려 URL을 반복하여 생성해 요청해서 받아오는 작업을 할 예정입니다!!!



자 이제 그럼 코드를 직접 공개해보겠습니다!! 



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import pandas_compat as pd
from bs4 import BeautifulSoup
import requests
import urllib.request as ul
import xmltodict
import json
import sys
import io
import re
 
from urllib.request import urlopen,Request
from urllib.parse import urlencode, quote_plus, unquote
 
name_ls = []
address_ls = []
open_date_ls = []
tel_no_ls = []
post_num_ls = []
clcd_ls = []
clcdnm_ls = []
emdongnm_ls = []
sggucdnm_ls = []
sggucd_ls = []
sidoCd_ls = []
sidocdnm_ls = []
xpos_ls = []
ypos_ls = []
cs



우선 사용할 패키지를 모두 import 해주시구요!!!


각 변수에 해당하는 값을 저장해주기 위해서 각각 리스트를 생성해줍니다!!


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
for j in range(1,1158,1) : 
    url='http://apis.data.go.kr/B551182/pharmacyInfoService/getParmacyBasisList?ServiceKey=당신의 서비스 키를 &pageNo='+ str(j)+'&numOfRows=20'
    req = requests.get(url)
    html = req.text
    soup = BeautifulSoup(html, 'html.parser')
    ItemList=soup.findAll('item'
    for i in range(0,len(ItemList),1):
        name = ItemList[i].find('yadmnm')
        name=re.sub("<yadmnm>","",str(name))
        name=re.sub("</yadmnm>","",str(name))
        name_ls.append(name)
        
        address = ItemList[i].find('addr')
        address=re.sub("<addr>","",str(address))
        address=re.sub("</addr>","",str(address))
        address_ls.append(address)
        
        open_date = ItemList[i].find('estbdd')
        open_date=re.sub("<estbdd>","",str(open_date))
        open_date=re.sub("</estbdd>","",str(open_date))
        open_date_ls.append(open_date)
        
        tel_no = ItemList[i].find('telno')
        tel_no=re.sub("<telno>","",str(tel_no))
        tel_no=re.sub("</telno>","",str(tel_no))
        tel_no_ls.append(tel_no)
        
        post_num = ItemList[i].find('postno')
        post_num=re.sub("<postno>","",str(post_num))
        post_num=re.sub("</postno>","",str(post_num))
        post_num_ls.append(post_num)
        
        clcd = ItemList[i].find('clcd')
        clcd=re.sub("<clcd>","",str(clcd))
        clcd=re.sub("</clcd>","",str(clcd))
        clcd_ls.append(clcd)
        
        sggucdnm = ItemList[i].find('sggucdnm')
        sggucdnm=re.sub("<sggucdnm>","",str(sggucdnm))
        sggucdnm=re.sub("</sggucdnm>","",str(sggucdnm))
        sggucdnm_ls.append(sggucdnm)
        
        sidocdnm = ItemList[i].find('sidocdnm')
        sidocdnm=re.sub("<sidocdnm>","",str(sidocdnm))
        sidocdnm=re.sub("</sidocdnm>","",str(sidocdnm))
        sidocdnm_ls.append(sidocdnm)
        
        xpos = ItemList[i].find('xpos')
        xpos=re.sub("<xpos>","",str(xpos))
        xpos=re.sub("</xpos>","",str(xpos))
        xpos_ls.append(xpos)
        
        ypos = ItemList[i].find('ypos')
        ypos=re.sub("<ypos>","",str(ypos))
        ypos=re.sub("</ypos>","",str(ypos))
        ypos_ls.append(ypos)
cs


자 가장 먼저 첫 번째 for문을 왜 1158까지 지정했냐!!!!!!


바로 모든 데이터를 긁어오기 위한 작업입니다 ㅎㅎ


먼저 테스트로 j에 1 값을 넣어서 페이지를 확인해 보면



가장 하단에 페이지 넘버, 한 페이지당 결과 수 를 보시면 각각 1, 20 이 들어가 있는 것을 확인할 수 있습니다!


바로 그 밑에!!! totalCount 부분 보이시나요?


그것 때문에 1158을 넣었던 건데요 자~ 설명을 드리면 한 페이지에 20개가 나와야하는데 전체가 23,146 개 이다?


23,146/20 은 약 1157.3 이라는 값이 나옵니다! 모든 것을 긁어 오려면 페이지가 1158 페이지가 필요한 것이죠!!


그래서 저렇게 지정한 것입니다!


더 편하게 할 수 있을 것 같은데...전 반 수작업으로 직접 확인후 값을 지정해줍니다!! 핳하!!





그렇게 각각 URL들을 요청해서 받아오는 변수 중 XML 구문의 앞에 <></> 에 각각 해당하는 값들을 지워준 후 리스트에 차곡 차곡 쌓아 갑니다!



그렇게 각각 잘 쌓였다면 데이터 프레임으로 만들어 줘야겠죠?


1
2
3
4
5
6
import pandas as pd
df=pd.DataFrame({'약국명': pd.Series(name_ls), '주소': pd.Series(address_ls), 
                 '개설일자': pd.Series(open_date_ls), '우편번호': pd.Series(post_num_ls), 
                 '전화번호': pd.Series(tel_no_ls),'주소2': pd.Series(sggucdnm_ls),
                 '서브주소': pd.Series(sidocdnm_ls), 'xpos': pd.Series(xpos_ls), 'ypos': pd.Series(ypos_ls),})
df['개설일자']=df['개설일자'].fillna('20210102')
cs


자 위와 같은 코드로 데이터 프레임을 만들어 주었습니다.


그리고 개설 일자가 null값들이 있어서 그냥 2021년 1월 2일로 넣어버렸습니다 ㅎㅎㅎ




df 를 확인해보니 잘~ 출력된 것을 확인할 수 있었습니다!!!



사진이 사라진 관계로.....



df.to_excel("df.xlsx", encoding="CP949")



위와 같은 명령어를 치시면 엑셀 파일로 저장이 됩니다! ㅎㅎ 인코딩은 한글 때문에 꼭 지정해 주셔야합니다!!!




자~ 이렇게 API를 통해 데이터를 받아오는 작업을 진행해 보았습니다!


생각보다 어렵지 않았죠? ㅎㅎ하핳



다들 외부데이터가 필요하실 때 이런 식으로 접근한다면 데이터의 부족함을 어느 정도 해소할 수 있지 않을 까 싶습니다!!


이상 긴글 읽어주셔서 감사합니다~



다음에 또 찾아오겠습니다!! :)

728x90
반응형

'데이터 수집 > API' 카테고리의 다른 글

특정 키워드 뉴스 카카오톡 자동 발송 구축하기 - (1)  (0) 2024.03.29
네이버 뉴스 API 정리  (0) 2024.03.26
T-map API  (2) 2020.07.18