[Data Prep] 파이썬을 활용한 공공데이터API 접근하기_미세먼지 통계 | BeautifulSoup, Open API
최근 3~4년간 사람들이 부쩍 미세먼지에 대한 관심이 높아졌다. 개인적인 생각은 미세먼지에 대해서 과거에 비해 심해졌다기 보다, 사람들의 인식이 삶의 질에 더 관심이 많아지면서 air quality에도 관심을 가졌기 때문일 것이라 생각하는데 내 생각이 맞는지 아니면 진짜 대기오염 수치가 나빠진 것인지에 대해 직접 데이터를 크롤링해 살펴보고자 한다.
크롤링 하기 전에, 다른 방법으로 공기오염 정도에 대한 통계를 제공하는지 살펴보려고 airkorea 사이트에 접속했다.
사이트에서 통계연보 및 월보의 형태로 데이터를 제공하기는 하지만, 매년 혹은 매월 데이터를 다운받아 취합하는 과정은 상당히 귀찮은 일이다.
내가 구현하고 싶은 것은 다음과 같다.
- 공공데이터 포털에 제공하는 api에 접속
- '종로구'에 있는 측정소에서 매월 측정한 데이터를 읽고, 리스트에 저장한다.
- 리스트에 저장된 데이터를 엑셀에 옮겨 저장한다.
이를 위해서 공공데이터 포털(data.go.kr) 내에 있는 '대기오염통계 서비스'에 접속해 api에 인증키를 받자. 아래 링크를 통해 접속이 가능하며, 아래 스크린샷의 활용신청을 통해 인증키를 받을 수 있다. (물론, 이후에 마이페이지에서 일반 인증키를 받아야 한다.)
https://www.data.go.kr/dataset/15000583/openapi.do?mypageFlag=Y
공공데이터포털
국가에서 보유하고 있는 다양한 데이터를『공공데이터의 제공 및 이용 활성화에 관한 법률(제11956호)』에 따라 개방하여 국민들이 보다 쉽고 용이하게 공유•활용할 수 있도록 공공데이터(Dataset)와 Open API로 제공하는 사이트입니다.
www.data.go.kr
위의 일련의 과정을 거친 후에, 참고문서를 열어보면 내가 찾고자 하는 대기오염 통계에 대한 설명은 33p 부터 있으니 참고하기 바란다.
34p 하단에 있는 REST(URI)를 살펴보자.
http://openapi.airkorea.or.kr/openapi/services/rest/ArpltnStatsSvc/getMsrstnAcctoLastDcsnDnsty?stationName=종로구&searchCondition=DAILY&pageNo=1&numOfRows=10&ServiceKey=서비스키
stationName : 측정소명
searchCondition : 데이터의 구분 조건인데, 매일(DAILY), 월별(MONTH), 연도별(YEAR)로 구분된다.
numOfRows : 데이터 수
ServiceKey : 내가 받은 인증키
위 URI에 서비스키 부분을 내 인증키로 바꿔 크롬 검색창에 검색해보면, 아래와 같이 나온다.
(searchConditon은 'MONTH', numOfRows는 500으로 설정)
xml로 쓰여진 미세먼지 통계 데이터에 올바르게 접근하고 있음을 확인할 수 있다. 이 페이지를 끝까지 내려보면 2018년 말까지 데이터만 등록되어 있는데, 아마 2019년 내용을 아직 업데이트하지 못했나 보다.
(원한다면 한국환경공단에 민원은 넣거나 정보공개 청구를 하면 되긴 하지만, 공공기관 직원의 노고를 아는 나로서는 그렇게 하지 않았다.)
- 공공데이터 포털에 제공하는 api에 접속,
- '종로구'에 있는 측정소에서 매월 측정한 데이터를 읽고, 리스트에 저장한다.
- 리스트에 저장된 데이터를 엑셀에 옮겨 저장한다.
내가 원하는 동작을 하도록 만든 코드는 아래와 같다.
from openpyxl import Workbook
from bs4 import BeautifulSoup
import requests
def main():
date = [] #측정한 연월을 저장할 리스트
pm10 = [] #pm10 데이터를 저장할 리스트
cert_key = "내가 받은 인증키"
url = "http://openapi.airkorea.or.kr/openapi/services/rest/ArpltnStatsSvc/getMsrstnAcctoLastDcsnDnsty?
stationName=종로구&searchCondition=MONTH&pageNo=1&numOfRows=500&ServiceKey=" + cert_key
req = requests.get(url) #공공데이터에 등록된 xml파일에 접근
html = req.text
soup = BeautifulSoup(html, 'html.parser')
for i in soup.find_all("datatime"): #측정년월, pm10평균을 각 리스트에 저장
date.append(i.text)
for i in soup.find_all("pm10avg"):
pm10.append(i.text)
wb = Workbook() #새로운 엑셀을 만들고, 그 이름을 미세먼지 통계로 지정
ws = wb.active
file_name = '미세먼지 통계.xlsx'
ws.cell(row=1, column=1).value = "date" #첫 행, 열 이름 지정
ws.cell(row=1, column=6).value = "pm10" #첫 행, 열 이름 지정
for row_index in range(1,len(date)+1): #리스트에 저장된 데이터를 순서대로 write
ws.cell(row=row_index+1, column=1).value = date[(row_index-1)]
ws.cell(row=row_index+1, column=2).value = pm10[(row_index-1)]
wb.save(filename = file_name) #마지막으로 파일이름으로 저장
if __name__ == "__main__":
main()
이전에 데이터 크롤링(crawling, scraping)와 엑셀에 저장하는 것을 참고하면 될 듯하고, 여기서 조금 새로운 것은 엑셀 워크북을 만들어서 새롭게 저장하는 코드를 사용했다는 점만 다르다.
비슷한 방식으로 공공에서 제공하는 데이터들을 비교적 쉽고 빠르게 가져올 수 있어 다른 활용에 무궁무진해 보인다.
주1) XML을 읽어올 때, 대문자를 사용하지 않도록 한다. 예시에서 dataTime 이런식으로 측정년월이 되어 있는데, python으로 읽을 때는 find_all("datatime")으로 사용해야 한다.
주2) 위에서는 pm10만 가져왔지만, 오존이나 이산화황 등 다양한 대기질 관련 데이터도 추가 가능하다. 다만, 리스트가 추가되고 코드가 더 길어질 것이기 때문에 생략하기로 한다.
주3) 인증키는 다른사람과 공유하지 않도록 주의한다.
주4) 리스트에 text형태로 저장하기 때문에 바로 활용하기가 어렵다. 따라서, 엑셀에서 제공하는 문자값을 숫자로 변환하는 기능을 활용하자. (사실, text가 아닌 숫자로 저장하는 방법을 아직 찾지 못했다.)
'Python > Data Prep' 카테고리의 다른 글
파이썬으로 여러 페이지에 있는 정부 보도자료 크롤링하기_페이지네이션 | Web Scraping (0) | 2021.10.04 |
---|---|
[Data Prep] 제멋대로인 주소(광역지자체명) 표준화하기 (0) | 2021.08.15 |
금감원 XML 파일(corp_code) python으로 읽어내기 (0) | 2020.03.14 |
[Data Prep] 파이썬 Openpyxl을 이용한 보도자료 내용 저장하기 (0) | 2020.03.02 |
[Data Prep] 파이썬으로 산업부 보도자료 크롤링 하기 (13) | 2020.02.23 |