인증키 발급부터 예외 처리, 그리고 판다스를 이용한 엑셀 저장법까지 데이터 수집을 위한 든든한 기초 체력을 모두 다졌습니다. 이제 이론을 넘어 진짜 살아있는 외부 데이터를 내 컴퓨터로 끌어오는 첫 번째 실전 프로젝트를 시작할 시간입니다.
우리가 도전할 첫 실전 주제는 바로 기상청에서 제공하는 '단기예보 조회 서비스' API입니다. 매일 아침 스마트폰으로 확인하는 날씨 정보를 내 파이썬 코드로 직접 수집해 보는 경험은 자동화의 재미를 체감하기에 가장 좋습니다. 기상청 API는 데이터의 양이 방대하고 구조가 복잡해 처음 접하면 헤매기 쉽지만, 데이터가 들어오는 규칙만 정확히 이해하면 누구나 실시간 예보 정보를 한눈에 정리할 수 있습니다.
기상청 API를 다룰 때 반드시 알아야 할 2가지 특수 규칙
기상청 단기예보 API는 일반적인 오픈 API와 달리, 기상청만의 고유한 규칙 두 가지를 이해해야 정상적인 데이터를 돌려받을 수 있습니다. 이 부분을 놓치면 백 퍼센트 빈 데이터나 에러 메시지를 만나게 됩니다.
첫 번째는 '기상청 격자 좌표(NX, NY)' 시스템입니다. 기상청은 우리가 흔히 쓰는 위도와 경도(예: 37.566, 126.978)를 그대로 사용하지 않고, 한반도를 바둑판 모양으로 나눈 고유의 격자 좌표를 사용합니다. 예를 들어 서울 시청 중심의 격자 좌표는 nx=60, ny=127입니다. 내가 원하는 지역의 날씨를 구하려면 공공데이터포털 가이드 문서에 첨부된 엑셀 파일을 열어 해당 행정구역의 nx, ny 값을 먼저 찾아두어야 합니다.
두 번째는 '발표 시각(Base Time)'의 제약입니다. 기상청 초단기실황 API는 매 시각 40분이 지나야 전 시간의 정시 데이터가 업데이트됩니다. 예를 들어 지금이 오전 10시 15분이라면, 아직 10시 데이터가 생성되지 않았기 때문에 base_time을 '0900'으로 요청해야 안전하게 데이터를 받아올 수 있습니다. 시간 계산 오류로 데이터가 누락되는 것을 막으려면 현재 분(Minute)을 체크해 40분 이전이면 이전 시간대의 데이터를 요청하는 안전 로직을 코드에 녹여내야 합니다.
기상청 초단기실황 API 수집 실전 코드
아래 코드는 서울 지역(nx=60, ny=127)의 실시간 날씨 요소를 수집하여 가독성 있게 정렬하는 전체 소스코드입니다. 기상청이 반환하는 영문 데이터 코드(T1H, REH 등)를 우리가 알아볼 수 있는 한글 명칭으로 변환하는 매핑 과정까지 포함되어 있습니다.
import requests
import pandas as pd
# 1. 기상청 초단기실황 주소 및 디코딩 인증키 설정
url = "http://apis.data.go.kr/1360000/VilageFcstInfoService_2.0/getUltraSrtNcst"
decoding_key = "여러분의_디코딩_인증키_입력"
# 2. 요청 파라미터 구성 (서울 중심부 기준)
# 실습을 위해 날짜와 시간은 가이드에 맞추어 고정값으로 테스트 후 현재 시간으로 확장하세요.
params = {
'serviceKey': decoding_key,
'pageNo': '1',
'numOfRows': '100',
'dataType': 'JSON',
'base_date': '20260709', # 수집하려는 날짜 YYYYMMDD
'base_time': '0600', # 매시 40분 이후 정시 데이터 발표 (예: 0600)
'nx': '60', # 서울 격자 X
'ny': '127' # 서울 격자 Y
}
# 기상청 영문 항목 코드를 한글로 바꾸기 위한 매핑 사전
category_map = {
'T1H': '기온(°C)',
'RN1': '1시간 강수량(mm)',
'REH': '습도(%)',
'PTY': '강수형태(코드)',
'WSD': '풍속(m/s)',
'VEC': '풍향(deg)'
}
try:
response = requests.get(url, params=params, timeout=10)
response.raise_for_status()
raw_data = response.json()
# 데이터 응답 상태 확인
result_code = raw_data['response']['header']['resultCode']
if result_code != '00':
print(f"[서버 에러] 메시지: {raw_data['response']['header']['resultMsg']}")
else:
# 알맹이 데이터가 들어있는 리스트 추출
items = raw_data['response']['body']['items']['item']
parsed_list = []
for item in items:
category_code = item['category']
# 우리가 필요한 핵심 날씨 항목만 필터링하여 저장
if category_code in category_map:
parsed_list.append({
'날짜': item['baseDate'],
'시간': item['baseTime'],
'날씨항목': category_map[category_code],
'측정값': item['obsrValue']
})
# 3. 판다스 데이터프레임으로 시각화 및 확인
df = pd.DataFrame(parsed_list)
print("\n--- 서울 지역 실시간 기상 실황 데이터 ---")
print(df.to_string(index=False))
# 4. 엑셀 파일로 백업 저장
df.to_excel("seoul_current_weather.xlsx", index=False)
print("\n[성공] 'seoul_current_weather.xlsx' 파일로 저장이 완료되었습니다.")
except Exception as e:
print(f"데이터 수집 중 오류가 발생했습니다: {e}")
수집된 데이터 알맹이 해석하는 노하우
코드를 실행해 보면 데이터프레임 형태로 정렬된 날씨 정보가 화면에 깔끔하게 출력됩니다. 기온(T1H)이나 습도(REH)는 24.5나 60 같은 직관적인 숫자로 나오기 때문에 그대로 활용하면 되지만, '강수형태(PTY)' 같은 항목은 조금 다릅니다. 비가 오는지 눈이 오는지 텍스트로 알려주는 것이 아니라 0, 1, 2 같은 숫자로 전달되기 때문입니다.
기상청 문서에 따르면 강수형태의 숫자 값은 다음과 같은 의미를 지닙니다: 0은 비나 눈이 오지 않는 맑은 상태, 1은 비, 2는 비와 눈이 섞인 상태(진눈깨비), 3은 눈, 4는 소나기를 뜻합니다. 만약 이 데이터를 활용해 날씨 알림 봇을 만들거나 블로그에 정보를 자동으로 포스팅하는 프로그램을 확장하고 싶다면, 조건문(if)을 활용해 숫자가 1일 때는 화면에 "비가 내리고 있습니다"라고 변환해 주는 가공 단계를 한 번 더 거쳐야 진정한 의미의 데이터 자동화 정보가 완성됩니다.
핵심 요약
기상청 단기예보 API는 위경도 대신 nx, ny라는 고유의 격자 좌표를 파라미터로 넘겨주어야 합니다.
데이터는 매 시각 40분이 지나야 안정적으로 업데이트되므로 시간 설정 시 40분 정체 구간을 고려해야 합니다.
영문 카테고리 코드와 강수형태 숫자값은 사용자가 읽기 좋은 한글과 기상 용어로 매핑하여 가공해야 가치가 높아집니다.
0 댓글