Sister Nosilv story

[TIL 3rd] 실제 기상청 Open API를 사용해보았다

by 노실언니

진행상황 

 Complete  -

 In progress  국민취업지원제도 1유형 11/12에 신청함─처리중

 In progress  내일배움캠프 Spring 5기 사전캠프 (24.11.18.月 ~ 24.12.20.金─총 33일 / 14:00~18:00 ─일일 4시간)

 In progress  웹개발기초 강의 듣기 ─ 3주차 듣는중

 To-do  내일배움캠프 Spring 5기 본캠프 (24.12.23.月 ~ 25.05.06.火 ─총 135일 / 9:00~21:00─일일 12시간)

 To-do  SQL 강의 듣기 & 퀘스트 하기

 To-do  혼공자바 읽기 & 퀘스트 하기


오늘 배운 이론은 [ Client↔Server ] 다.

1) Server가 하나의 은행이면, API는 그 은행 속의 예금창구, 대출창구, 환전창구, · · · 이다.

2) API는 Server가 마련해놓은 다양한 창구(Interface)들로 API마다 요청하는 방식, 건내주는 데이터 등이 다르다.

3) Client는 Server에게 무언가 요청하는 모든 것으로 사람보다는 응용 프로그램에게 쓰는 역할이다.

 └ (예) 브라우저 → 서버의 특정 API에게 HTML/CSS/JS 파일 요청

 └ (예) 웹서비스 → 서버의 특정 API에게 원하는 데이터 요청

4) Client가 API에게 자신이 원하는 것을 요청하는 방식에는 get 방식과 post 방식이 있는데,

  강의에서는 직관적이고 쉬운 그러나 보안에는 취약한 get 방식만을 사용했다.

get 방식은 url에 요청정보가 노출된다 (주황색 부분)

5) 웹 서비스는 언어 JS를 사용하여, 특정 Server의 특정 API에게 원하는 Data를 요청해서 받아올 수 있다.

 나는 JQuery의 fetchget방식으로 쓰인 URL 사용하여,

 서울시 Open API에게 실시간 미세먼지 상황을 요청하고 받아서 사용하는 연습을 했다.

let url = "http://openapi.seoul.go.kr:블라블라";
fetch(url)								// url에 요청해서 데이터 fetch해오기
	.then((result) => result.json())	// 받은 data에 result라는 이름을 붙이고 => 얘를 json화 하기
    .then((jsondata) => {				// json화한 data에 jsondata라는 이름을 붙이고 =>
    	let mise = jsondata["RealtimeCityAir"]["row"][0]["IDEX_NM"];
        // jsondata에서 키가 RealtimeCityAir인 값을 가져오기
        // 가져온 값에서 키가 row인 값을 가져오기
        // 가져온 값에서 index가 0인 값을 가져오기
        // 가져온 값에서 키가 IDEX_NM인 값을 mise에 넣기
        $("#mise_info").text(mise);     // ID가 mise_info인 태그의 content를 mise 값으로 만들기
    });

문제 : 실제 기상청 API를 사용하는 것은 차원이 다르구나

웹개발기초 3주차에서 초반에 제공했던 서울시 미세먼지 OpenAPI 주소는 문제없이 작동했지만

두 가지 실습에서 사용하라고 준 스파르타의 미세먼지API와 날씨정보API는 작동하지 않았다.

API 이거 어떻게 해

 

미세먼지API를 사용해야 하는 실습(3-11)은 문제없이 작동했던 서울시 미세먼지 OpenAPI를 사용했는데,

날씨정보API를 사용해야하는 실습(3-12)은 그런게 없어서, 그럼 기상청 OpenAPI를 사용해보자!고 생각했는데

그 막연한 생각에 오늘 하루가 전부 잡아먹혔다ㅋㅋㅋㅠㅠㅠ

 

1. 일단은, 공공데이터 포털에 가입(카카오로 함)을 하고 기상청_단기예보 조회서비스의 초단기실황조회를 활용신청했다.

 

그 이후의 과정에서 엄청 헤맸는데, 지금와서 생각해보니

https://apis.data.go.kr/1360000/VilageFcstInfoService_2.0/getUltraSrtNcst? 뒤에 온갖 필요한 요청변수를 기입한다음

fetch 명령어에다가 사용하면 됐던거였다.

 

 

2. 미리보기로 확인해보기

미리보기의 확인 버튼을 누르니 다양한 항목이 떴다. get방식이구나!

- ServiceKey 항목에는 나의 인증키를 기입하면 된다.

- pageNo는 안 바꿔도 되는데 궁금해서 바꿔 봄

- dataType는 JSON으로 기입했다. default값이 XML이니까 꼭 기입해야한다.

- base_date, base_time은 원하는 시간대인데 javascipt의 변수를 사용해서 실시간이 되도록 만들어줘야한다.

 일단은 20241120/0600으로 기입했다.

- nx, ny는 원하는 위치인데, 오픈API활용가이드라는 참고문서의 엑셀파일을 활용해서 내가 원하는 위치를 기입했다.

참고문서 확인하기


이렇게 한 후에 미리보기 버튼을 누르니 뭔가 정상적인 JSON 창이 새롭게 떴다.

그리고 URL을 보니까 진짜 정직하게 배운대로 짜여있더라

클라이언트가 API에게 주는 정보는 &로 연결됨

다만 연습용으로 사용했던 URL들보다 훨씬 길고, API에게 제공해야하는 데이터들도 많으니까, 복잡해서 헤맸던거였다.

이제 감을 좀 잡았다.

 

 

3. javascript 코드의 변수url을 기상청openAPI의 URL값으로 초기화했다.

let url = "https://apis.data.go.kr/1360000/VilageFcstInfoService_2.0/getUltraSrtNcst?serviceKey=내가 복붙한 인증키값&pageNo=1&numOfRows=10&dataType=JSON&base_date=" + year_month_date + "&base_time=" + hour_minute + "&nx=62&ny=125";

유의할 점은 base_date랑 time은 실시간이어야하니까 base_date=에서 스트링을 끊고 마구마구 짜깁기해주었다.

 

 

4. 조사하는 시간대가 실시간이 되도록 변수값을 설정해준다.

new Date() 를 사용해서 실시간 날짜시간대를 받은 후에, base_date와 base_time의 값으로 사용할 수 있는 형태로 가공해주었다.

그렇게 가공한 값을 year_month_date와 hour_minute에 넣고 이 두 변수를 URL에 사용한다.

console.log(확인하고자 하는 변수) 를 적극적으로 활용해서 값이 정확한지 확인해주었는데
덕분에 막힐 때 원인을 찾아서 문제를 금방 해결할 수 있다.

 

var today = new Date();
var year = today.getFullYear();
var month = today.getMonth() + 1; // 0부터 시작해서 1더해주기
var date = today.getDate();
var hour = today.getHours();
var minute = today.getMinutes();

var year_month_date = "" + year;
var hour_minute = "";

// 한 자리 수인 경우 앞에 0 붙이기
if (month < 10) { year_month_date += "0"; }
year_month_date += month;

if (date < 10) { year_month_date += "0"; }
// 한 시간 전 기상 데이터를 가져올 예정이므로 자정은 전 날로 ㄱㄱ
if (hours == 0) { hour = 24; date--; }
year_month_date += date;
hour--; // 한 시간 전 기상데이터를 가져오기

if (hour < 10) { hour_minute += "0"; }
hour_minute += hour;
if (minute < 10) { hour_minute += "0"; }
hour_minute += minute;

 

 

5. 아까 받은 정보 분석해서 원하는 값을 fetch하는 코드 완성하기

 

오픈 API 활용가이드의 워드파일 마지막 부분에는 서버에서 받아온 값들 중 자료구분코드에 대한 설명이 들어있다.

기온 카테고리명은 T1H이다.

이 파일을 읽고 자료구분코드가 T1H 인 자료가 기온이라는 것을 확인했다.

그  후, 아까 연습삼아 받았던 JSON 데이터 중 category: "T1H" 인 자료를 찾아 다녔고, item 리스트의 4번째가 기온에 관련된 자료임을 확인하였다. 즉, 내려받은 데이터에서 키가 response인 값에 접근하고, 그 값 중 키가 body인 값에 접근하고, 그 값 중 키가 items인 값에 접근하고, 그 값 중 키가 item인 값에 접근하고, 그 값 중 인덱스값이 4인 값에 접근하면, 그 값 중 키가 obsrValue인 값이 기온이다.

category가 T1H인 요소의 obsrValue가 기온!

이렇게 fetch하여 결론적으로 기온(obsrValue)을 찾아내는 코드와 그 값을 원하는 위치에 붙여넣는 코드를 작성했다.

fetch(url)
          .then((res) => res.json())
          .then((data) => {
            let temperature_celsius =
              data["response"]["body"]["items"]["item"][3]["obsrValue"];
            $("#temperature").text(temperature_celsius);
          });

 

 

결과

ㅠㅠ

 

이 일을 해결하며, 

 기상청 API를 사용해보려고 구글링을 엄청 했다. 내가 원하는 정보가 한 글에 쫘르륵 있지 않았고, 이 글에서는 이 정보만, 저 글에서는 저 정보만 주워서 합쳐서 어떻게든 해결을 하긴 했다. 크롬 탭에 한 20개 정도 달려 있었던 듯... 그냥, '스파르타에서 준 URL이 이상하니까 넘어가자'랄지 '실시간은 힘드니까 고정 시간값으로 fetch하자'랄지 중간에 빨리 끝내버리고 싶은 유혹도 많았다.

 이악물고ㅋㅋㅋ원래 처음에 목표했던 형태로 해결을 하긴 했다. 그런데, '다시 이 API를 쓰려고 하면, 내가 할 수 있을까?' 하는 걱정이 들었다. 이건 내가 강의를 듣고나서 드는 걱정과 같은 결이다. 일단은 하긴 했는데 머리에 안 남은 것 같은 그 느낌과 같았다.

 그래서 이렇게 TIL에 남겨보았는데, 실제로 다시 글을 쓰려니 난감했고 4시간이 걸렸다. 그렇지만, 이렇게 글로 남기길 잘했다는 생각이 든다. 그 이유는 이제는 기상청API뿐만 아니라 다른 openAPI를 써야할 때도 내가 쓸 수 있을 것 같은 약간의 확신이 생겼기 때문이다. 허우... 🫠

반응형

블로그의 정보

노력하는 실버티어

노실언니

활동하기