지난 번에 활용신청 해둔 오픈 API를 활용해볼 것이다.
활용신청을 하면 일반 인증키(UTF-8)이 주어지는데 get하는 과정에서 utf-8로 인코딩이 되기 때문에 utf-8로 인코딩된 데이터가 아닌 디코딩된 데이터를 get에 넘겨주어야 한다.
Google에 url decoder라고 검색한 후 아무 사이트에서 서비스키(utf-8)를 디코딩하고 복사&붙여넣기 하면 된다.
In:
import requests
payload = {'serviceKey': '디코딩한 서비스키',
'numOfRow': '10',
'pageNum': '1',
'sidoName': '서울',
'ver': '1.3',
'_returnType': 'json'
}
response = requests.get('http://openapi.airkorea.or.kr/openapi/services/rest/ArpltnInforInqireSvc/getCtprvnRltmMesureDnsty', payload)
print(response)
print(response.json())
print(type(response.json()))
response_data = response.json()
items = response_data['list']
for i in items:
print(i['stationName'], "미세먼지 등급 "+i['pm10Grade1h'], "초미세먼지 등급 "+i['pm25Grade1h'])
Out:
<Response [200]>
{'list': [{'_returnType': 'json', 'coGrade': '1', 'coValue': '0.8', 'dataTerm': '', 'dataTime': '2021-01-15 17:00', 'khaiGrade': '2', 'khaiValue': '87', 'mangName': '도시대기', 'no2Grade': '2', 'no2Value': '0.035', 'numOfRows': '10', 'o3Grade': '1', 'o3Value': '0.020', 'pageNo': '1', 'pm10Grade': '2', 'pm10Grade1h': '3', 'pm10Value': '101', 'pm10Value24': '60', 'pm25Grade': '2', 'pm25Grade1h': '3', 'pm25Value': '66', 'pm25Value24': '30', 'resultCode': '', 'resultMsg': '', 'rnum': 0, 'serviceKey': '', 'sidoName': '', 'so2Grade': '1', 'so2Value': '0.004', 'stationCode': '', 'stationName': '영등포구', 'totalCount': '', 'ver': ''}, {'_returnType': 'json', 'coGrade': '1', 'coValue': '0.7', 'dataTerm': '', 'dataTime': '2021-01-15 17:00', 'khaiGrade': '2', 'khaiValue': '86', 'mangName': '도시대기', 'no2Grade': '2', 'no2Value': '0.034', 'numOfRows': '10', 'o3Grade': '1', 'o3Value': '0.022', 'pageNo': '1', 'pm10Grade': '2', 'pm10Grade1h': '3', 'pm10Value': '109', 'pm10Value24': '66', 'pm25Grade': '2', 'pm25Grade1h': '3', 'pm25Value': '61', 'pm25Value24': '28', 'resultCode': '', 'resultMsg': '', 'rnum': 0, 'serviceKey': '', 'sidoName': '', 'so2Grade': '1', 'so2Value': '0.003', 'stationCode': '', 'stationName': '금천구', 'totalCount': '', 'ver': ''}, {'_returnType': 'json', 'coGrade': '1', 'coValue': '0.6', 'dataTerm': '', 'dataTime': '2021-01-15 17:00', 'khaiGrade': '2', 'khaiValue': '87', 'mangName': '도시대기', 'no2Grade': '1', 'no2Value': '0.030', 'numOfRows': '10', 'o3Grade': '1', 'o3Value': '0.016', 'pageNo': '1', 'pm10Grade': '2', 'pm10Grade1h': '3', 'pm10Value': '99', 'pm10Value24': '66', 'pm25Grade': '2', 'pm25Grade1h': '3', 'pm25Value': '57', 'pm25Value24': '30', 'resultCode': '', 'resultMsg': '', 'rnum': 0, 'serviceKey': '', 'sidoName': '', 'so2Grade': '1', 'so2Value': '0.004', 'stationCode': '', 'stationName': '용산구', 'totalCount': '', 'ver': ''}, {'_returnType': 'json', 'coGrade': '1', 'coValue': '0.9', 'dataTerm': '', 'dataTime': '2021-01-15 17:00', 'khaiGrade': '2', 'khaiValue': '88', 'mangName': '도로변대기', 'no2Grade': '2', 'no2Value': '0.050', 'numOfRows': '10', 'o3Grade': '1', 'o3Value': '0.012', 'pageNo': '1', 'pm10Grade': '2', 'pm10Grade1h': '3', 'pm10Value': '117', 'pm10Value24': '68', 'pm25Grade': '2', 'pm25Grade1h': '3', 'pm25Value': '67', 'pm25Value24': '32', 'resultCode': '', 'resultMsg': '', 'rnum': 0, 'serviceKey': '', 'sidoName': '', 'so2Grade': '1', 'so2Value': '0.004', 'stationCode': '', 'stationName': '영등포로', 'totalCount': '', 'ver': ''}, {'_returnType': 'json', 'coGrade': '1', 'coValue': '0.9', 'dataTerm': '', 'dataTime': '2021-01-15 17:00', 'khaiGrade': '2', 'khaiValue': '100', 'mangName': '도로변대기', 'no2Grade': '2', 'no2Value': '0.048', 'numOfRows': '10', 'o3Grade': '1', 'o3Value': '0.015', 'pageNo': '1', 'pm10Grade': '2', 'pm10Grade1h': '3', 'pm10Value': '106', 'pm10Value24': '69', 'pm25Grade': '2', 'pm25Grade1h': '3', 'pm25Value': '68', 'pm25Value24': '35', 'resultCode': '', 'resultMsg': '', 'rnum': 0, 'serviceKey': '', 'sidoName': '', 'so2Grade': '1', 'so2Value': '0.005', 'stationCode': '', 'stationName': '홍릉로', 'totalCount': '', 'ver': ''}, {'_returnType': 'json', 'coGrade': '1', 'coValue': '0.7', 'dataTerm': '', 'dataTime': '2021-01-15 17:00', 'khaiGrade': '3', 'khaiValue': '101', 'mangName': '도시대기', 'no2Grade': '2', 'no2Value': '0.040', 'numOfRows': '10', 'o3Grade': '1', 'o3Value': '0.018', 'pageNo': '1', 'pm10Grade': '2', 'pm10Grade1h': '3', 'pm10Value': '109', 'pm10Value24': '73', 'pm25Grade': '3', 'pm25Grade1h': '3', 'pm25Value': '65', 'pm25Value24': '36', 'resultCode': '', 'resultMsg': '', 'rnum': 0, 'serviceKey': '', 'sidoName': '', 'so2Grade': '1', 'so2Value': '0.004', 'stationCode': '', 'stationName': '강동구', 'totalCount': '', 'ver': ''}, {'_returnType': 'json', 'coGrade': '1', 'coValue': '0.8', 'dataTerm': '', 'dataTime': '2021-01-15 17:00', 'khaiGrade': '2', 'khaiValue': '95', 'mangName': '도로변대기', 'no2Grade': '2', 'no2Value': '0.043', 'numOfRows': '10', 'o3Grade': '1', 'o3Value': '0.020', 'pageNo': '1', 'pm10Grade': '2', 'pm10Grade1h': '3', 'pm10Value': '110', 'pm10Value24': '75', 'pm25Grade': '2', 'pm25Grade1h': '3', 'pm25Value': '54', 'pm25Value24': '32', 'resultCode': '', 'resultMsg': '', 'rnum': 0, 'serviceKey': '', 'sidoName': '', 'so2Grade': '1', 'so2Value': '0.005', 'stationCode': '', 'stationName': '천호대로', 'totalCount': '', 'ver': ''}, {'_returnType': 'json', 'coGrade': '1', 'coValue': '0.7', 'dataTerm': '', 'dataTime': '2021-01-15 17:00', 'khaiGrade': '2', 'khaiValue': '90', 'mangName': '도시대기', 'no2Grade': '2', 'no2Value': '0.037', 'numOfRows': '10', 'o3Grade': '1', 'o3Value': '0.022', 'pageNo': '1', 'pm10Grade': '2', 'pm10Grade1h': '3', 'pm10Value': '85', 'pm10Value24': '62', 'pm25Grade': '2', 'pm25Grade1h': '3', 'pm25Value': '52', 'pm25Value24': '31', 'resultCode': '', 'resultMsg': '', 'rnum': 0, 'serviceKey': '', 'sidoName': '', 'so2Grade': '1', 'so2Value': '0.004', 'stationCode': '', 'stationName': '송파구', 'totalCount': '', 'ver': ''}, {'_returnType': 'json', 'coGrade': '1', 'coValue': '0.6', 'dataTerm': '', 'dataTime': '2021-01-15 17:00', 'khaiGrade': '2', 'khaiValue': '94', 'mangName': '도로변대기', 'no2Grade': '2', 'no2Value': '0.051', 'numOfRows': '10', 'o3Grade': '1', 'o3Value': '0.011', 'pageNo': '1', 'pm10Grade': '2', 'pm10Grade1h': '3', 'pm10Value': '108', 'pm10Value24': '74', 'pm25Grade': '2', 'pm25Grade1h': '3', 'pm25Value': '51', 'pm25Value24': '30', 'resultCode': '', 'resultMsg': '', 'rnum': 0, 'serviceKey': '', 'sidoName': '', 'so2Grade': '1', 'so2Value': '0.004', 'stationCode': '', 'stationName': '화랑로', 'totalCount': '', 'ver': ''}, {'_returnType': 'json', 'coGrade': '1', 'coValue': '0.6', 'dataTerm': '', 'dataTime': '2021-01-15 17:00', 'khaiGrade': '3', 'khaiValue': '109', 'mangName': '도시대기', 'no2Grade': '1', 'no2Value': '0.015', 'numOfRows': '10', 'o3Grade': '2', 'o3Value': '0.038', 'pageNo': '1', 'pm10Grade': '2', 'pm10Grade1h': '3', 'pm10Value': '117', 'pm10Value24': '69', 'pm25Grade': '3', 'pm25Grade1h': '4', 'pm25Value': '78', 'pm25Value24': '38', 'resultCode': '', 'resultMsg': '', 'rnum': 0, 'serviceKey': '', 'sidoName': '', 'so2Grade': '1', 'so2Value': '0.003', 'stationCode': '', 'stationName': '도봉구', 'totalCount': '', 'ver': ''}], 'parm': {'_returnType': 'json', 'coGrade': '', 'coValue': '', 'dataTerm': '', 'dataTime': '', 'khaiGrade': '', 'khaiValue': '', 'mangName': '', 'no2Grade': '', 'no2Value': '', 'numOfRows': '10', 'o3Grade': '', 'o3Value': '', 'pageNo': '1', 'pm10Grade': '', 'pm10Grade1h': '', 'pm10Value': '', 'pm10Value24': '', 'pm25Grade': '', 'pm25Grade1h': '', 'pm25Value': '', 'pm25Value24': '', 'resultCode': '', 'resultMsg': '', 'rnum': 0, 'serviceKey': 'z4477D+LAxRqNz5Pa+XsleZidEULVe7FFXZBRBrsQ7aNFY/OP1QWXKK5ojCffga04tH/VtWH+AGSgUFOKYTY0w==', 'sidoName': '서울', 'so2Grade': '', 'so2Value': '', 'stationCode': '', 'stationName': '', 'totalCount': '', 'ver': '1.3'}, 'ArpltnInforInqireSvcVo': {'_returnType': 'json', 'coGrade': '', 'coValue': '', 'dataTerm': '', 'dataTime': '', 'khaiGrade': '', 'khaiValue': '', 'mangName': '', 'no2Grade': '', 'no2Value': '', 'numOfRows': '10', 'o3Grade': '', 'o3Value': '', 'pageNo': '1', 'pm10Grade': '', 'pm10Grade1h': '', 'pm10Value': '', 'pm10Value24': '', 'pm25Grade': '', 'pm25Grade1h': '', 'pm25Value': '', 'pm25Value24': '', 'resultCode': '', 'resultMsg': '', 'rnum': 0, 'serviceKey': 'z4477D+LAxRqNz5Pa+XsleZidEULVe7FFXZBRBrsQ7aNFY/OP1QWXKK5ojCffga04tH/VtWH+AGSgUFOKYTY0w==', 'sidoName': '서울', 'so2Grade': '', 'so2Value': '', 'stationCode': '', 'stationName': '', 'totalCount': '', 'ver': '1.3'}, 'totalCount': 40}
<class 'dict'>
영등포구 미세먼지 등급 3 초미세먼지 등급 3
금천구 미세먼지 등급 3 초미세먼지 등급 3
용산구 미세먼지 등급 3 초미세먼지 등급 3
영등포로 미세먼지 등급 3 초미세먼지 등급 3
홍릉로 미세먼지 등급 3 초미세먼지 등급 3
강동구 미세먼지 등급 3 초미세먼지 등급 3
천호대로 미세먼지 등급 3 초미세먼지 등급 3
송파구 미세먼지 등급 3 초미세먼지 등급 3
화랑로 미세먼지 등급 3 초미세먼지 등급 3
도봉구 미세먼지 등급 3 초미세먼지 등급 4
XML(eXtensible Markup Language)
In:
import requests
import xml.etree.ElementTree as tree
payload = {'serviceKey': '디코딩된 서비스키',
'numOfRow': '10',
'pageNum': '1',
'sidoName': '서울',
'ver': '1.3',
}
response = requests.get('http://openapi.airkorea.or.kr/openapi/services/rest/ArpltnInforInqireSvc/getCtprvnRltmMesureDnsty', payload)
print(response)
root = tree.fromstring(response.text)
body = root.find('body')
items = body.find('items')
for item in items.iter('item'):
# <stationName>측정소이름</stationName>
print(item.find('stationName').text, "미세먼지 등급 " + item.find('pm10Grade1h').text, "초미세먼지 등급 "+item.find('pm25Grade1h').text)
Out:
<Response [200]>
영등포구 미세먼지 등급 3 초미세먼지 등급 3
금천구 미세먼지 등급 3 초미세먼지 등급 3
용산구 미세먼지 등급 3 초미세먼지 등급 3
영등포로 미세먼지 등급 3 초미세먼지 등급 3
홍릉로 미세먼지 등급 3 초미세먼지 등급 3
강동구 미세먼지 등급 3 초미세먼지 등급 3
천호대로 미세먼지 등급 3 초미세먼지 등급 3
송파구 미세먼지 등급 3 초미세먼지 등급 3
화랑로 미세먼지 등급 3 초미세먼지 등급 3
도봉구 미세먼지 등급 3 초미세먼지 등급 4
In:
import requests
import xml.etree.ElementTree as tree
num_of_rows = 10
has_next = True
page_num = 1
while has_next:
payload = {'serviceKey': 'z4477D+LAxRqNz5Pa+XsleZidEULVe7FFXZBRBrsQ7aNFY/OP1QWXKK5ojCffga04tH/VtWH+AGSgUFOKYTY0w==',
'numOfRow': num_of_rows,
'pageNo': page_num,
'sidoName': '서울',
'ver': '1.3',
}
response = requests.get('http://openapi.airkorea.or.kr/openapi/services/rest/ArpltnInforInqireSvc/getCtprvnRltmMesureDnsty', payload)
print(response)
root = tree.fromstring(response.text)
body = root.find('body')
items = body.find('items')
for item in items.iter('item'):
# <stationName>측정소이름</stationName>
print(item.find('stationName').text, "미세먼지 등급 " + item.find('pm10Grade1h').text, "초미세먼지 등급 "+item.find('pm25Grade1h').text)
total_count = int(body.find('totalCount').text)
current_page_num = int(body.find('pageNo').text)
print("page", current_page_num)
if num_of_rows * current_page_num >= total_count:
has_next = False
page_num += 1
Out:
<Response [200]>
영등포구 미세먼지 등급 2 초미세먼지 등급 3
금천구 미세먼지 등급 2 초미세먼지 등급 3
용산구 미세먼지 등급 2 초미세먼지 등급 3
영등포로 미세먼지 등급 2 초미세먼지 등급 2
홍릉로 미세먼지 등급 2 초미세먼지 등급 2
강동구 미세먼지 등급 2 초미세먼지 등급 3
천호대로 미세먼지 등급 2 초미세먼지 등급 3
송파구 미세먼지 등급 2 초미세먼지 등급 2
화랑로 미세먼지 등급 2 초미세먼지 등급 2
도봉구 미세먼지 등급 2 초미세먼지 등급 3
page 1
<Response [200]>
정릉로 미세먼지 등급 2 초미세먼지 등급 2
신촌로 미세먼지 등급 2 초미세먼지 등급 3
강변북로 미세먼지 등급 2 초미세먼지 등급 3
동작대로 중앙차로 미세먼지 등급 2 초미세먼지 등급 2
시흥대로 미세먼지 등급 2 초미세먼지 등급 3
광진구 미세먼지 등급 2 초미세먼지 등급 3
공항대로 미세먼지 등급 2 초미세먼지 등급 2
서대문구 미세먼지 등급 2 초미세먼지 등급 3
관악구 미세먼지 등급 2 초미세먼지 등급 2
강남대로 미세먼지 등급 2 초미세먼지 등급 3
page 2
<Response [200]>
종로구 미세먼지 등급 2 초미세먼지 등급 2
양천구 미세먼지 등급 2 초미세먼지 등급 3
중랑구 미세먼지 등급 2 초미세먼지 등급 3
마포구 미세먼지 등급 2 초미세먼지 등급 2
강서구 미세먼지 등급 2 초미세먼지 등급 3
강남구 미세먼지 등급 2 초미세먼지 등급 3
노원구 미세먼지 등급 2 초미세먼지 등급 3
성동구 미세먼지 등급 2 초미세먼지 등급 3
은평구 미세먼지 등급 2 초미세먼지 등급 2
동작구 미세먼지 등급 2 초미세먼지 등급 3
page 3
<Response [200]>
서초구 미세먼지 등급 2 초미세먼지 등급 3
도산대로 미세먼지 등급 2 초미세먼지 등급 3
성북구 미세먼지 등급 2 초미세먼지 등급 2
한강대로 미세먼지 등급 2 초미세먼지 등급 2
강북구 미세먼지 등급 2 초미세먼지 등급 3
종로 미세먼지 등급 2 초미세먼지 등급 2
구로구 미세먼지 등급 2 초미세먼지 등급 3
중구 미세먼지 등급 2 초미세먼지 등급 2
청계천로 미세먼지 등급 2 초미세먼지 등급 3
동대문구 미세먼지 등급 2 초미세먼지 등급 3
page 4
'파이썬 Python' 카테고리의 다른 글
[Python] 초급 12 클래스 예제 (0) | 2021.02.21 |
---|---|
초급 10, 11 클래스와 상속 (0) | 2021.01.23 |
초급 8 REST, JSON (0) | 2021.01.14 |
초급 7 딕셔너리, 프로그램 설계 (0) | 2021.01.14 |
초급 6 파일 입출력, 변수 범위 (0) | 2021.01.13 |