코드

[PHP] 기상청 중기예보를 캐러셀로 보여주는 위젯 (매우 허접합니다 ㅠㅠ)

by 이니스프리 posted Sep 28, 2018
?

단축키

Prev이전 문서

Next다음 문서

ESC닫기

크게 작게 위로 아래로 댓글로 가기 인쇄
Extra Form
라이선스 MIT

안녕하세요?


기상청 중기예보 RSS를 파싱하여 캐러셀 형태로 보여주는 위젯을 만들어보았습니다.


제가 실력이 형편없는 초보자이지만 이렇게 소스를 계속 작성해보고 올리는 이유는 


여기 스포어에 계신 개발자 분들께 여쭤보면서 한 수 배우려는 것이 주된 목적이고,


부수적으로는 제가 올린 스크립트를 제 스스로 보면서 더 분발해서 열심히 공부하려는 취지도 있습니다.


일단 허접한 위젯의 외형은 다음과 같습니다.



캐러설로 보여주는 부분은 Owl Carousel을 사용했습니다.


움짤을 보면 자동 스크롤이 되는 것으로 오해하실 수도 있으나 


그 기능은 활성화하지 않았고 버튼을 클릭해야 스크롤이 되도록 만들었습니다.



일단 아미나를 기준으로 만들었지만 그누보드와는 별개로 작동하고


JQuery를 로드하는 한 줄을 추가하면 독립적으로 실행할 수도 있습니다.

(이건 의도한 것이 아니라 제가 실력이 부족해서 아미나에서 위젯을 설정하는 php 파일을 만들지 못했습니다 ㅠㅠ)



데이터는 기상청 홈페이지의 중기예보 RSS를 이용했습니다. 


아웃도어 활동을 즐기는 분들에게는 오늘의 날씨만큼이나 중기예보가 중요한데요.


아미나에서 작동하는 중기예보 위젯을 찾지 못해서 제가 만들어봤습니다 ㅠㅠ



설명이 길었는데 스크립트는 다음과 같습니다.


Owl Carousel 관련 파일을 건드리지 않기 위해서 이 스크립트에 CSS 스크립트까지 집어넣었습니다 -_-;



<?php
if (!defined('_GNUBOARD_')) exit; // 개별 페이지 접근 불가
?>

<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="utf-8">
      <link rel="stylesheet" href="/css/owl.carousel.min.css">
      <link rel="stylesheet" href="/css/owl.theme.default.min.css">
      <script src="/owl.carousel.min.js"></script>
  </head>
</html>


<?php
  header('Content-Type: text/html; charset=utf-8');
  $url = "http://www.weather.go.kr/weather/forecast/mid-term-rss3.jsp?stnId=109";
  // Id - 강원: 105, 충북: 131, 충남: 133, 전북: 146, 전남: 156, 경북:143, 경남: 159, 제주: 184
  $ch = cURL_init();
 
  cURL_setopt($ch, CURLOPT_URL, $url);
  cURL_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
 
  $response = cURL_exec($ch);
  cURL_close($ch);

  $rss = simplexml_load_string($response);
 
  $rss_time = $rss->channel->item->title; // 발표시간 출력
  $rss_time = explode('-', $rss_time);
  echo "<strong>", $rss_time[1], "</strong><br />";
 
  $rss_comment = $rss->channel->item->description->header->wf; // 코멘트 출력
  echo $rss_comment, "<br /><br />";
?>


<!-- owl-carousel의 색상을 변경-->
<style>
.owl-theme .owl-controls .owl-page.active span {
    border: 2px solid gray;
}

.owl-theme .owl-controls .owl-page span {
    border: 2px solid gray;
}
</style>

<!--owl-carousel의 옵션 변경-->
<script type="text/javascript">
//<![CDATA[
$(document).ready(function(){
  $('.owl-carousel').owlCarousel({
    loop:true,
    autoWidth:true,
    items:3,
    margin:10,
    navigation:true,
    navigationText : ['<', '>'],
})
});
//]]>
</script>

<!-- carousel에 들어갈 태그-->
<!-- 기상청 RSS가 5일 간은 오전 오후로, 나머지 3일은 오전 오후 구분 없이 예보합니다-->
<div class="owl-carousel owl-theme">
  <div class="item" style="width:200px">
    <?php
        $n=0;
        $when = $rss->channel->item->description->body->location[0]->data[$n]->tmEf;
        $when = explode(' ', $when);
        $when = $when[0]; // 날짜만 변수에 넣음
        echo "<strong><font color = 'blue'>", $when, "</font></strong><br />";
        echo "AM: ";
        skystatus($n, $rss);
        echo "<br />PM: ";
        skystatus($n+1, $rss);
        echo "<br />";

        $tmn = $rss->channel->item->description->body->location[0]->data[$n]->tmn; // 온도 출력
        $tmx = $rss->channel->item->description->body->location[0]->data[$n]->tmx;
        echo $tmn, " ~ ", $tmx, "C <br />";
    ?>
  </div>
  <div class="item" style="width:200px">
    <?php
        $n=2;
        $when = $rss->channel->item->description->body->location[0]->data[$n]->tmEf;
        $when = explode(' ', $when);
        $when = $when[0]; // 날짜만 변수에 넣음
        echo "<strong><font color = 'blue'>", $when, "</font></strong><br />";
        echo "AM: ";
        skystatus($n, $rss);
        echo "<br />PM: ";
        skystatus($n+1, $rss);
        echo "<br />";
           
        $tmn = $rss->channel->item->description->body->location[0]->data[$n]->tmn; // 온도 출력
        $tmx = $rss->channel->item->description->body->location[0]->data[$n]->tmx;
        echo $tmn, " ~ ", $tmx, "C <br />";
    ?>
  </div>
  <div class="item" style="width:200px">
    <?php
        $n=4;
        $when = $rss->channel->item->description->body->location[0]->data[$n]->tmEf;
        $when = explode(' ', $when);
        $when = $when[0];  // 날짜만 변수에 넣음
        echo "<strong><font color = 'blue'>", $when, "</font></strong><br />";
        echo "AM: ";
        skystatus($n, $rss);
        echo "<br />PM: ";
        skystatus($n+1, $rss);
        echo "<br />";
           
        $tmn = $rss->channel->item->description->body->location[0]->data[$n]->tmn; // 온도 출력
        $tmx = $rss->channel->item->description->body->location[0]->data[$n]->tmx;
        echo $tmn, " ~ ", $tmx, "C <br />";
    ?>
  </div>
  <div class="item" style="width:200px">
    <?php
        $n=6;
        $when = $rss->channel->item->description->body->location[0]->data[$n]->tmEf;
        $when = explode(' ', $when);
        $when = $when[0];  // 날짜만 변수에 넣음
        echo "<strong><font color = 'blue'>", $when, "</font></strong><br />";
        echo "AM: ";
        skystatus($n, $rss);
        echo "<br />PM: ";
        skystatus($n+1, $rss);
        echo "<br />";
           
        $tmn = $rss->channel->item->description->body->location[0]->data[$n]->tmn; // 온도 출력
        $tmx = $rss->channel->item->description->body->location[0]->data[$n]->tmx;
        echo $tmn, " ~ ", $tmx, "C <br />";
    ?>
  </div>
  <div class="item" style="width:200px">
    <?php
        $n=8;
        $when = $rss->channel->item->description->body->location[0]->data[$n]->tmEf;
        $when = explode(' ', $when);
        $when = $when[0]; // 날짜만 변수에 넣음
        echo "<strong><font color = 'blue'>", $when, "</font></strong><br />";
        echo "AM: ";
        skystatus($n, $rss);
        echo "<br />PM: ";
        skystatus($n+1, $rss);
        echo "<br />";
           
        $tmn = $rss->channel->item->description->body->location[0]->data[$n]->tmn; // 온도 출력
        $tmx = $rss->channel->item->description->body->location[0]->data[$n]->tmx;
        echo $tmn, " ~ ", $tmx, "C <br />";
    ?>
  </div>
  <div class="item" style="width:200px">
    <?php
      $n=10;
        $when = $rss->channel->item->description->body->location[0]->data[$n]->tmEf; // 날짜 출력
        $when = explode(' ', $when);
        $when = $when[0];  // 날짜만 변수에 넣음
        echo "<strong><font color = 'blue'>", $when, "</font></strong><br />";
        skystatus($n, $rss);
        echo "<br />";
 
        $tmn = $rss->channel->item->description->body->location[0]->data[$n]->tmn; // 온도 출력
        $tmx = $rss->channel->item->description->body->location[0]->data[$n]->tmx;
        echo $tmn, " ~ ", $tmx, "C <br /><br />";
    ?>
  </div>
  <div class="item" style="width:200px">
    <?php
      $n=11;
        $when = $rss->channel->item->description->body->location[0]->data[$n]->tmEf; // 날짜 출력
        $when = explode(' ', $when);
        $when = $when[0];
        echo "<strong><font color = 'blue'>", $when, "</font></strong><br />";
        skystatus($n, $rss);
        echo "<br />";
 
        $tmn = $rss->channel->item->description->body->location[0]->data[$n]->tmn; // 온도 출력
        $tmx = $rss->channel->item->description->body->location[0]->data[$n]->tmx;
        echo $tmn, " ~ ", $tmx, "C <br /><br />";
    ?>
  </div>  
  <div class="item" style="width:200px">
    <?php
      $n=12;
        $when = $rss->channel->item->description->body->location[0]->data[$n]->tmEf; // 날짜 출력
        $when = explode(' ', $when);
        $when = $when[0];
        echo "<strong><font color = 'blue'>", $when, "</font></strong><br />";
        skystatus($n, $rss);
        echo "<br />";
 
        $tmn = $rss->channel->item->description->body->location[0]->data[$n]->tmn; // 온도 출력
        $tmx = $rss->channel->item->description->body->location[0]->data[$n]->tmx;
        echo $tmn, " ~ ", $tmx, "C <br /><br />";
    ?>
  </div>
</div>


<?php
function skystatus($n, $rss) // 구름량에 관한 함수 선언
{
  $sky = $rss->channel->item->description->body->location[0]->data[$n]->wf;
  $sky = iconv("UTF-8", "EUC-KR", $sky);
  if (preg_match('/맑음/', $sky) == 1)
  {
    echo "<img src = 'http://www.weather.go.kr/images/icon/NW/NB01.png'/>";
  }
  elseif (preg_match('/조금/', $sky) == 1)
  {
    echo "<img src = 'http://www.weather.go.kr/images/icon/NW/NB02.png'/>";
  }
  elseif (preg_match('/많음/', $sky) == 1)
  {
    echo "<img src = 'http://www.weather.go.kr/images/icon/NW/NB03.png'/>";
  }
  else
  {
    echo "<img src = 'http://www.weather.go.kr/images/icon/NW/NB04.png'/>";
  }
  $sky = iconv("EUC-KR", "UTF-8", $sky);
  echo $sky;
}
?>

(스크립트를 제대로 긁어서 붙여넣었는데 코드 하이라이터에서 보여줄 때 깨지는 부분이 있네요 ㅜㅜ 부득이 파일로 첨부하였습니다)

widget.php 



제가 이 스크립트를 짜면서 궁금했던 부분이 있어서 좀 여쭤보겠습니다 ㅠㅠ


1. 제가 beautifulsoup에 익숙해져서 그런지 simplexml_load_string으로 


$when = $rss->channel->item->description->body->location[0]->data[$n]->tmEf;


이런 식으로 셀렉터를 길게 나열하는 것이 효율적이지 않다고 느껴지는데요.


더 효율적인 방법이나 더 나은 parser는 없는지 여쭤봅니다. 


차라리 정규식을 바로 사용하는 것이 효율적이었을까요?


아참 simplexml_load_file로 url을 바로 불러오지 않고 cURL로 불러와서 simplexml_load_string로 다시 불러온 것은


제가 사용한 웹호스팅(닷홈 무료) 쪽인지 기상청 쪽인지 모르겠지만 막아놓은 것 같더군요 ㅠㅠ



2. 마지막에 함수 선언해 놓은 부분에서 


$sky = iconv("UTF-8", "EUC-KR", $sky) 로 변수 하나씩 변환하여 정규식으로 비교하고 


다시 $sky = iconv("EUC-KR", "UTF-8", $sky) 로 변환해서 출력해야 


인코딩이 안 깨지고 제대로 비교하고 출력이 되던데요.


원래 이렇게 해야하는 것인지 아니면 제가 인코딩 변환에 대해 잘 몰라서 이런 우회적인 방법을 사용한 것인지 모르겠네요 ㅠㅠ



3. 제가 사용한 무료 웹호스팅 환경에서 Owl Carousel이 매뉴얼대로 완벽하게 작동하지는 않는 것 같구요.


캐러셀의 대상이 되는 div 태그 내에 폰트어썸을 사용하면 캐러셀 전체가 깨지던데요 ㅜㅜ


텍스트를 캐러셀로 더 쉽게 구현할 수 있는 방법이 있을까요?


이미지 파일은 bxslider를 많이 사용하길래 시도해봤는데요. 


이 스크립트처럼 텍스트만 사용하려니 깨져서 보이더군요.



4. <!-- carousel에 들어갈 태그--> 부분을 원래 n이 1씩 증가하는 PHP의 for 문으로 짜보려고 했는데요.


for 문의 내용으로 html인 div 태그가 들어가서 for 문을 사용하지 못하고 


결국 ctrl + c, v 해서 스크립트를 길게 나열하게 되었는데요.


이런 경우에 반복문을 돌릴 수 있는 다른 해결책이 없는지 여쭤봅니다.



여러모로 부족하고 장황한 글을 읽어주신 모든 분께 감사드립니다!


그럼 즐겁고 뜻깊은 9월의 마지막 주말 되시기를 기원합니다 ^^



Articles

1 2 3 4