import os import requests import csv from datetime import datetime, timedelta import time # 1. API 인증키 설정 def get_env_variable(var_name): if os.path.exists(".env"): with open(".env", "r") as f: for line in f: if "=" in line: k, v = line.split("=", 1) if k.strip() == var_name: return v.strip() return os.getenv(var_name) API_KEY = get_env_variable("WEATHER_KEY") or get_env_variable("KMA_API_KEY") # 2. 정밀 좌표 설정 (NetCDF 추출값) TARGET_LAT = 34.925323 TARGET_LON = 127.710838 # 3. 추출 기간 설정 start_dt = datetime(2026, 4, 1, 0, 0) end_dt = datetime(2026, 5, 7, 23, 55) # 4. API 설정 BASE_URL = "https://apihub.kma.go.kr/api/typ01/url/sfc_nc_var.php" OBS_ELEMENTS = "ta,hm,td,wd_10m,ws_10m,uu,vv,rn_ox,vs" INTERVAL = 5 def extract_all(): current_dt = start_dt all_data = [] total_hours = int((end_dt - start_dt).total_seconds() / 3600) + 1 count = 0 print(f"--- 연속 데이터 추출 시작 (총 {total_hours}개 구간) ---") output_filename = "weather_data_continuous_20260401_20260507.csv" keys = ["tm", "ta", "hm", "td", "wd_10m", "ws_10m", "uu", "vv", "rn_ox", "vs"] with open(output_filename, 'w', newline='', encoding='utf-8-sig') as f: writer = csv.DictWriter(f, fieldnames=keys) writer.writeheader() while current_dt <= end_dt: # 1시간 단위 요청 tm1 = current_dt tm2 = current_dt + timedelta(minutes=55) # 12개 데이터 (5분 간격) if tm2 > end_dt: tm2 = end_dt params = { "tm1": tm1.strftime("%Y%m%d%H%M"), "tm2": tm2.strftime("%Y%m%d%H%M"), "obs": OBS_ELEMENTS, "itv": INTERVAL, "lon": TARGET_LON, "lat": TARGET_LAT, "help": 0, "authKey": API_KEY } try: response = requests.get(BASE_URL, params=params, timeout=30) response.raise_for_status() rows = [] for line in response.text.strip().split('\n'): if line.startswith('#') or not line.strip(): continue parts = [p.strip() for p in line.replace(',', ' ').split()] if len(parts) >= 10: rows.append({ "tm": parts[0], "ta": parts[1], "hm": parts[2], "td": parts[3], "wd_10m": parts[4], "ws_10m": parts[5], "uu": parts[6], "vv": parts[7], "rn_ox": parts[8], "vs": parts[9] }) if rows: writer.writerows(rows) count += 1 if count % 50 == 0: print(f" 진행률: {count}/{total_hours} 구간 완료 ({current_dt.strftime('%Y-%m-%d %H:%M')})") except Exception as e: print(f" Error at {tm1}: {e}") current_dt += timedelta(hours=1) # API 부하 방지를 위한 미세 지연 (필요 시) # time.sleep(0.05) print(f"\n--- 추출 완료: {output_filename} ---") if __name__ == "__main__": extract_all()