2018 Nam Insik Portfolio site ː Designed by werty.co.kr ː nis@werty.co.kr
 
 
 
 
 
 
 
 
모바일웹에서 기상청 날씨(실황) api 가져와서 파싱해서 노출까지 자바스크립트로 만들기

<포스팅 업데이트 : 2017년 4월 11일>

다시한번 해당 내용으로 data.go.kr 문의를 보냈습니다.
원문은 https://www.data.go.kr/information/QNA_0000000000014129/qna.do 이 곳을 참고해보시면 됩니다.
결론부터 말씀드리자면 api를 제공하는 입장에서 크로스도메인은 보안상의 이유로 허용할 수 없다고 합니다.
라이브러리가 안되는건 다른 라이브러리를 사용해서든 크로스도메인을 스스로 알아서 해결하여 사용하라는 이야기입니다.
참고로 전 다른 라이브러리들을 이용해서 시도해 보았으나 이 원리가 yahoo api를 거쳐 다녀오는 형태의 라이브러리들인데 아예 yahoo api 조차에서 진행이 안되는거라 어떤 라이브러리를 써도 같습니다. ㅠ

그리고 답변 중에 ‘크로스도메인 같은 경우 자바스크립트 보안 정책으로 인해 웹브라우저에서 막는 내용’ 이라는 이야기가 있는데요.  웹브라우저에서 막는 기능이기 때문에 어찌할 수 없다는 이야기로 해석됩니다.

결론을 말씀드리자면 현재로써는 자바스크립트로 기상청 API로 구현해낼 수 있는 방법이 없습니다.


<포스팅 업데이트 : 2017년 4월 10일>

기상청에서 제공하는 api는 자바스크립트로 구현하기 힘든 상황입니다.
이유는 키를 이용한 호출 결과와 크로스 도메인 두 문제가 해결되지 않으면 앞으로도 해결해 나갈 수 없습니다.
크로스 도메인 문제로 data.go.kr에 문의한 결과 ‘다른 사용자의 경우 xdomainajax (구글 검색 참고) 라는 라이브러리를 통해 해당 내용을 해결한 사례가 있으니 참고해주시길 바랍니다.’ (아마 지금 보시는 이 글인 듯합니다. 밑에 크로스 도메인을  해결할 수 있는 방법을 써놓았었거든요.

그리고 두번째는 호출입니다.  크로스 도메인을 임시로 해결하였다고 한들 ajax로 호출하고 난뒤 돌아오는 값이 이제 빈값입니다. (success 임에도 불구하구요.)  밑에 많은 분들이 댓글로 빈값이 온다 그러는데 바로 이 겁니다.  결과 값이 빈 값으로 들어옵니다.  하지만 웹으로 똑같은 호출 url을 열면 빈값이 아니라 데이터가 나오지요.  

이론적으로는 맞는데 쓸 수 없는 api 입니다.  외부에서 활용할 수 있게 api를 만들었으면 크로스도메인을 서버에서 허용해줘야하고,  url로 브라우저 접속하여 제대로 나온다고 끝이 아니라 직접 호출이 정상적으로 되는지 확인을 안하고 만들어놨다고 해놓은 상태이니 이걸 담당하는 사람도 없고 상담하시는 분도 건너 건너 이야기해 주시니 답답하네요.ㅠ


<포스팅 업데이트 : 2016년 2월 22일>

기상청에서 제공하는 api 구조가 바뀌어서 제대로 반영되지 않았던 내용을 수정하였습니다. 추가로 확인해보니 이제 새로운 api인 (신)동네예보정보조회서비스를 하나 더 제공하고 기존에 제공되어졌던 것은 (구)동네예보정보조회서비스로 변경되었습니다.  여러분께서는 지금 이 글은 구버전이므로 참고만 하시는 것을 추천드립니다.


시작하면서..

앞으로 글은 장문이 될 것 같아 역시 말이 좀 짧습니다.

기분이 나쁘시더라도 정보를 빠르게 얻어가기 위함이라 생각하시고 양해 부탁드립니다.


아무리 구글을 검색해도 기상청 날씨 API 가지고 데이터를 노출하는 것까지 나와있는 내용이 없었다.

이상하게 순수 클라이언트단에서 처리할 수 있는 자바스크립트 관련 내용이 gridx, gridy 변환, api 주소로 ajax에서 호출해오는 것까지만 나와있다.

그런데 이 다음부터 난관에 들어서게 된다.

바로 ajax로 호출하게 되면 다른 도메인에 있는 정보를 불러와야하기 때문에 보안 정책에 걸려서 불러오지 못하게 된다.

이는 역시 플러그인으로 해결할 수 있다.

그러나 기상청에서 가져온 API json 데이터의 형식이 안타깝게도 보이지 않는 공백때문에 오류가 나게 된다.

그리고 실황정보(예보 말고)를 가져오고 싶은데 대부분의 API는 동네 예보만을 가져오는 정보였다.

아래 포스팅 내용은 정답은 아니지만 그래도 최대한 기상청의 날씨 실황정보를 API를 불러와서 파싱하고 값을 노출하는 것까지 해보고자 한다.

계속 더 좋은 답이 나오면 업데이트 하도록 하겠다.

우리는 답을 찾을것이다 늘 그랬듯이..


1. 인증키 발급

일단 실황정보 API를 받기 위해 인증키를 발급 받자.

무료다.

https://www.data.go.kr/

위 링크로 가서 회원가입 후 활용신청하면 된다.

 

승인은 신청한지 얼마 지나지 않아 승인이 될 것이고, 마이페이지 가면 저렇게 인증키가 보이게 된다.

이렇게 비공개해야할 인증키를 공개해도 되나 생각하실까봐 미리 이야기하자면 인증키는 금방 재발급 받을 수 있다.

(포스팅이 끝나고 재발급 버튼만 누르면~ 끝!)

여튼 상세 기능 정보 보면 일일트래픽이 있다. 하루 동안 불러올 수 있는 횟수 제한이다.

어느 날씨 api가 좋고, 어느 api가 횟수가 많고 이런거 떠들라고 포스팅하려는거 아니니까 그런건 검색하면 잘 정리된 글들 많다.

다음은 코드 작성해보자.

 

2. 내 위치 값 가져오기

아래는 전부 자바스크립트 코드이니 알아서 js파일 안에 적어 넣도록 하자.

하나의 파일안에 담을 내용이지만 설명을 넣어야해서 함수별로 나눠서 쓰도록 하겠다.

모바일 웹브라우저의 geolocation을 이용해서 gps를 실행시키고자 한다.

gps가 없는 일반 pc 브라우저는 아마 통신사 isp 업체와 관련된 위치가 나올 것이다.

여튼 함수 설명에 지오로케이션이 있다면 값을 가져와서 locationSuccess 함수로 콜백하게 되어있다.

locationSuccess 함수외에 에러와 옵션은 크게 바꿀 일이 없으니 그냥 두자.

이제 gps로 내 위치의 위도와 경도값을 가져왔는데 이걸 그대로 쓸 수 없다.

기상청은 기상청만의 위치를 나누는 면적 계산이 다르기 때문이다. (기상청 gridx, gridy 검색하면 이유를 알 수 있다.)

여튼 위 함수에서 rs는 위치 변환하여 반환받은 값을 가진다.

그런 후에 그 값을 xml2jsonCurrentWth 함수로 보낸다.

일단 rs 위치 변환 함수부터 보자.

매우 길다.

진짜 길다.

그냥 복사 붙여넣기 해서 쓰자.

기상청에서 만든 코드라서 활용하기만 하면 된다.

궁금하면 구글 검색하면 친절히 설명을 쓴 글들이 있다. (다시 말해 본인은 포스팅 제목과 관련된 설명만 작성 중이다.)

이제 위치 변환된 값으로 api 정보를 가져와보자.

 

3. 위치에 맞는 실황 정보 API 불러오기

위 코드 중 apikey 에 이전에 발급받은 인증키를 넣으면 된다.

날짜와 시간은 실황 조회 api를 접근할 때 입력해야하기 때문에 초반부에 넣었다.

또한 이 실황 조회가 항상 현재 시간 기준으로 조회 될 수 있는게 아니다.

발표시간이 따로 있다.

또 발표시간도 매 정각마다이긴 한데 또 조회 기준 시간도 다르다.

이게 참 복잡한데 예를 들자면,

오후 3시 29분에 조회를 하면 2시 발표된 걸 불러와야하고,

오후 3시 31분에 조회를 하면 3시에 발표된 걸 불러와야한다.

발표정각을 기준으로 한시간 단위이지만 조회30분을 기준으로 한시간 단위다.

왜인지 궁금하면 기상청에 물어보면 된다.

여튼 만약에 위 예제대로 3시 29분에 3시 발표된 걸 불러오려고 하면 없는 데이터로 나온다.

그걸 대비하기 위에 위 코드에 알아서 계산되게 코드 짜놓았다.

그러니 그냥 인증키만 수정해서 쓰면된다.

 

4. 가져온 데이터 손보기

Ajax 호출 후 success 안에는 가져온 데이터에 빈공간엔터로 인해 생기는 오류를 대비해서 rplLine 함수를 통해 변환 작업을 거친다.

변환작업을 거치면 기상청 api안에 숨어있는 안보이는 빈공간을 오류없이 변환해 준다.

다시 변환된 텍스트를 $.parseJSON을 통해 json 형식으로 값을 변환하게 된다.

  • rainsnow : 없음(0), 비(1), 비/눈(2), 눈(3)
  • sky : 맑음(1), 구름조금(2), 구름많음(3), 흐림(4)
  • temp : 온도

가져온 눈또는 비 상태 (rainsnow) 와 하늘 상태 (sky), 온도(temp)를 이쁘게 사용자 화면에 뿌려주면 된다.

html에 id가 contentText 인 요소안에 값이 노출될 것이다.

여기까지 완성되었다면 getLocation함수를 실행시키는 것으로 모든 코드가 작동되게 해보자.

 

5. 크로스 도메인 해결

결과화면이 뿌듯하게 나오나 싶었다.

깔끔하게 작동된다면 더 바랄 것이 없겠지만 아마 크로스 도메인 때문에 아래와 같은 콘솔 메시지를 보게 될 것이다.

뭐라 떠드는지 몰라도 No ‘Access-Control-Allow-Origin’ header is present on the requested resource. 이 글만 봐도 접근할 수 없단다.

바로 도메인이 다른 곳의 파일을 불러올 때 보안에 문제가 생기기 때문에 막아버린 현상인데 그럼 ajax로 호출할 때  dataType: “jsonp” 로 하면 가능하다라고 생각할 것이다.

물론 이론상으로는 jsonp로 다른 도메인 파일 가져올 수 있다.

그런데 jsonp로 기상청 api가 안불러와진다.

그래서 본인이 ajax 호출하는 코드에  // dataType: “jsonp”, 이렇게 주석처리해서 작동안되게 해놨다.

도전해보고 싶은 사람은 해봐도 좋다. (성공하면 피드백 좀… ㅠㅠ)

여튼 답은 플러그인이다.

에 아래 코드 입력하고 파일을 업로드한다.

해당 플러그인 파일은 http://james.padolsey.com/javascript/cross-domain-requests-with-jquery/ 이 곳에 받을 수 있다.

이제 작동해보자.

본인은 값을 활용하여 이미지가 노출되게 하였다.

여기에 발표시간도 노출하고 그외 api에서 제공해주는 다른 값들도 넣어주면 된다.

기상청에서 api 다운받을 때 가이드 문서 있다.

그 문서에 엄청 많은 정보를 제공해주고 있으니 활용해보면 좋을 것 같다.


예제 파일

http://werty.co.kr/blog/labfile/weatherSample/

샘플 압축 파일


마치면서

기상청 api는 불안한 점이 많다.

api를 제공하는 서버가 접속이 안되는 경우가 빈번하게 발생하기 때문이다.

서버에서 정상으로 호출되는 경우는 이렇게 값이 잘 나오게 된다.

그러나 가끔 이렇게 호출되지 않고 엄하게 서버 오류 메세지가 나오게 된다.

어느 API를 쓰는지는 본인의 몫이다.

nain

이메일 : nis@naminsik.com

리뉴얼하려고 생각한지가 어느덧 3년이 지났다. ㅠ 망...
.