사이트 내 전체검색
PHP
구글 날씨 API를 활용한 날씨 출력 (PHP용
로빈아빠
https://cmd.kr/php/821 URL이 복사되었습니다.

본문

구글에서 제공하는 기능중에 개인화 페이지가 있습니다.
개인화 페이지는 웹젯을 통하여 본인이 원하는 스타일대로 페이지를 구성하는 것으로 타 포털에서도 동일한 기능을 제공하는지는 모르겠으나 상당히 잘 되어 있는 것으로 생각된다.
아무래도 대세인 AJAX, Flex 등 이름도 생소한 여러 기술들이 사용되었을 것으로 판단된다.

이 개인화 페이지에서 제공하는 웹젯중 날씨 정보를 제공해주는 웹젯이 있다.

이 웹젯을 사용하여 다른 페이지에서도 날씨 정보를 아주 훌륭히 보여줄 수 있으며 XML정보만 파싱하는 정도로 구현도 매우 쉽다.

20090202190416.jpg 
(왼쪽 상단에 있는것이 날씨 웹젯)

보통 검색엔진에서 '구글 날씨 API'를 찾아보면 여러정보를 찾을수가 있는데 구글에서 제공하는 공식적인 API는 아닌것 같다.
http://code.google.com에서 제공하는 공식적인 API 목록 중에는 보이지 않으며 비공식적으로 사용되는 것으로 생각됨. (틀릴수도 있음)

본 API를 이용하기 위해서는 다음과 같이 URL로 날씨 정보를 요청하면 그에 대한 데이터를 XML 데이터로 돌려줍니다.
서울의 날씨정보를 요청해 하려면 다음과 같은 URL을 입력합니다.

http://www.google.co.kr/ig/api?weather=seoul

그러면 다음과 같이 날씨 정보가 XML로 응답됩니다.
URL만으로도 알수 있듯이 각 지역별 날씨는 weather= 뒤에 도시명을 영문으로 입력해 주면 해당 도시의 날씨 정보가 전달됩니다.
예를 들어 청주의 경우는 아래와 같이 입력합니다.

http://www.google.co.kr/ig/api?weather=cheongju


20090202192550.jpg 

대충 보아도 월, 화, 수요일의 날씨 정보를 알수가 있습니다.
그러나 이 정보를 가지고 우리는 보기좋게 날씨 정보를 표시하여야 합니다.
그러기 위해서는 위 XML 데이터를 파싱하여야 하는데 웹언어인 PHP로 파싱하도록 하겠습니다.

일부 이를 구현하신 다른 고수님들께서는 매우 복잡한 방법으로 (즉 XML을 파싱하는 것이 아니라 문자열 그대로를 분석) 처리하는 것을 본적이 있습니다. 그러나 PHP에서는 SimpleXML 이라는 XML을 처리가능한 객체로 변환해주고 매우 쉽고 유용한 기능들을 제공하고 있습니다.

PHP버전이 5.* 버전대 이상이어야 하는 것으로 알고 있습니다.
이를 이용해 위 XML을 매우 쉽게 처리할 수 가 있습니다.

우선 간단히 처리하는 코드를 살펴봅니다.
 

 1  <?

 2  $xml_data= @file_get_contents("http://www.google.co.kr/ig/api?weather=seoul");  

 3  $xml_data = iconv("EUC-KR","UTF-8", $xml_data);

 4

 5  if ($xml_data)

 6  {

 7     $xml = new SimpleXMLElement($xml_data);

 8

 9     echo "<pre>";

10     print_r($xml);

11     echo "</pre>";

12  }

13  ?>

 
 먼저 위 소스중 다소 생소한 함수를 중심으로 살펴 보겠습니다.

2번 라인의 file_get_contents()는 파일의 내용을 읽어 문자열 데이터로 읽어오는 역활을 합니다.
즉 URL값을 인자로 넘김으로써 XML데이터를 스트링 값으로 받게됩니다.
위에서 우리가 브라우저에서 통해서 본 XML 데이터를 문자열로 받게 되는 것입니다.
(자세한 것은 http://www.php.net 의 함수설명을 참조하세요)

3번 라인은 EUC-KR 인코딩을 되는데 이를 UTF-8로 인코딩을 변환하는 것입니다.
이 라인을 빼면 결과가 나오지 않습니다. SimpleXML 파서가 EUC-KR 인코딩을 처리 못하는것이 아닌가 짐작을 해 보지만 정확한건 저도 모르겠네요. ^^

7번 라인은 XML 데이터를 포함하는 SimpleXMLElement 객체를 선언합니다.
10번 라인을 통해  $xml 객체를 출력해 봅니다.
print_r()은 변수에 관한 정보를 사람이 읽기 편하게 출력해 주는 역할을 합니다.
(자세한 것은 http://www.php.net 의 함수설명을 참조하세요, 이 함수는 친절히도 한글설명도 있네요)

그러면 결과가 다음과 같이 나옵니다.

20090203150328.jpg

위에서 본 XML 데이터를 처리하여 SimpleXMLElement 객체의 데이터 정보가 표시됩니다.
대충 살펴 보아도 도시면, 날씨정보 등이 보이는 것을 확인할 수 있습니다.

위 데이터 구조는 다음과 같이 되어 있습니다.

SimpleXMLElement
(
[weather]
    (
    [forecast_information]     

        (
        [city]
        [postal_code]
        ......
        )
   &bsp;[current_conditions]
        (
        [condition]
        [temp_f]
        ......
        )
    [forecast_conditions]
        (
        [0]
            (
            [day_of_week]
            [low]
             ....
            )
        [1]
            (
            [day_of_week]
            [low]
             ....
            )
        )
    )
)

대충보아도 해당 도시에 대한 정보(forecast_information), 현재날씨(current_conditions), 다음날의 날씨예보(forecast_conditions) 크게 세부분으로 구성되는것을 볼수 있습니다.
특히 forecast_conditions부분은 [0], [1] 등 동일한 항목이 배열로 저장되어 있는 것을 확인할 수 있습니다.

우리는 SimpleXMLElement 객체를 통하여 우리가 원하는 정보를 추출해 내어 화면에 표시해 주시기만 하면 됩니다.
그러면 원하는 결과를 추력해 보도록 하겠습니다.

위 코드에 출력하는 코드를 추가해 보겠습니다.

 1  <?

 2  $xml_data= @file_get_contents("http://www.google.co.kr/ig/api?weather=seoul");  

 3  $xml_data = iconv("EUC-KR","UTF-8", $xml_data);

 4

 5  if ($xml_data)

 6  {

 7     $xml = new SimpleXMLElement($xml_data);

 8

 9     $cc_condition = $xml->weather->current_conditions->condition->attributes();

10     $cc_temp_c = $xml->weather->current_conditions->temp_c->attributes();

11     $cc_humidity = $xml->weather->current_conditions->humidity->attributes();

12     $cc_icon = $xml->weather->current_conditions->icon->attributes();

13     $cc_wind_condition = $xml->weather->current_conditions->wind_condition->attributes();
14
15     $cc_condition = iconv("UTF-8", "EUC-KR", $cc_condition);

16     $cc_temp_c = iconv("UTF-8", "EUC-KR", $cc_temp_c);

17     $cc_humidity = iconv("UTF-8", "EUC-KR", $cc_humidity);

18     $cc_icon = iconv("UTF-8", "EUC-KR", $cc_icon);

19     $cc_wind_condition = iconv("UTF-8", "EUC-KR", $cc_wind_condition);
20 
21     echo "날씨 : " . $cc_condition . "<br>";

22     echo "온도 : " . $cc_temp_c . "<br>";

23     echo "습도 : " . $cc_humidity . "<br>";

24     echo "아이콘 : <img src='http://www.google.co.kr" . $cc_icon . "'><br>";

25     echo "바람 : " . $cc_wind_condition . "<br>"

26  }

28  ?> 


먼저 SimpleXMLElement 객체에서 각 데이터 값을 가져오는 것은 PHP에서 클래스를 선언하여 객체를 선언한 후 객체의 맴버변수를 읽어오는것과 비슷합니다. SimpleXMLElement 객체에서는 attributes()라는 함수로 데이터값을 읽어오고 있습니다. (9~13번 라인)

15~19번 라인은 3번라인에서 XML 처리를 위해 UTF-8로 인코딩하다보니 브라우저에서 한글코드를 제대로 인식하지 못해 깨지는 경우가 많습니다. 그래서 아예 한글 코드를 EUC-KR로 다시 변경하는 것입니다.

21~25번까지는 출력이고요. 출력결과는 아래 화면입니다.

200902031503280.jpg

프로그래머들은 이런순간에 희열을 느끼도 화면에 우리가 원하는 데이터가 표시되었습니다.
결과를 보시면 습도는 이미 데이터에 '습도:'라는 문자열이 포함되어 있습니다. 바람도 마찬가지로 '바람:' 문자열이 포함되어 있고요.
이건 감안하셔서 필요가 없으실 경우는 문자열을 자르거나 해서 사용하시면 되겠습니다.
아이콘은 <img>태그 google에서 제공하는 아이콘을 사용하였습니다. 아이콘 값을 직접 뿌려보시면 '/image/weather/haze.gif'라는 값이 뿌려줍니다. 이를 <img>태그로 표시한 것입니다.

그러면 오늘의 날씨를 뿌리는 것은 다 되었습니다.
구글 API에서는 3일까지의 예보를 같이 제공합니다. 이 정보는 forecast_conditions라는 배열정보로 제공되었습니다.
이를 처리하는 코드를 추가하여 완복한 코드를 보겠습니다.

 

 1  <?

 2  $xml_data= @file_get_contents("http://www.google.co.kr/ig/api?weather=seoul");  

 3  $xml_data = iconv("EUC-KR","UTF-8", $xml_data);

 4

 5  if ($xml_data)

 6  {

 7     $xml = new SimpleXMLElement($xml_data);

 8

 9     $cc_condition = $xml->weather->current_conditions->condition->attributes();

10     $cc_temp_c = $xml->weather->current_conditions->temp_c->attributes();

11     $cc_humidity = $xml->weather->current_conditions->humidity->attributes();

12     $cc_icon = $xml->weather->current_conditions->icon->attributes();

13     $cc_wind_condition = $xml->weather->current_conditions->wind_condition->attributes();
14
15     $cc_condition = iconv("UTF-8", "EUC-KR", $cc_condition);

16     $cc_temp_c = iconv("UTF-8", "EUC-KR", $cc_temp_c);

17     $cc_humidity = iconv("UTF-8", "EUC-KR", $cc_humidity);

18     $cc_icon = iconv("UTF-8", "EUC-KR", $cc_icon);

19     $cc_wind_condition = iconv("UTF-8", "EUC-KR", $cc_wind_condition);
20 
21     echo "날씨 : " . $cc_condition . "<br>";

22     echo "온도 : " . $cc_temp_c . "<br>";

23     echo "습도 : " . $cc_humidity . "<br>";

24     echo "아이콘 : <img src='http://www.google.co.kr" . $cc_icon . "'><br>";

25     echo "바람 : " . $cc_wind_condition . "<br><br>";
26
27     for ($i=0; $i<4; $i++)

28     {

29        $fc_day_of_week[$i] = $xml->weather->forecast_conditions[$i]->day_of_week->attributes();

30        $fc_low[$i] = $xml->weather->forecast_conditions[$i]->low->attributes();

31        $fc_high[$i] = $xml->weather->forecast_conditions[$i]->high->attributes();

32        $fc_icon[$i] = $xml->weather->forecast_conditions[$i]->icon->attributes();

33        $fc_condition[$i] = $xml->weaher->forecast_conditions[$i]->condition->attributes();

34

35        $fc_day_of_week[$i] = iconv("UTF-8", "EUC-KR", $fc_day_of_week[$i]);

36        $fc_low[$i] = iconv("UTF-8", "EUC-KR", $fc_low[$i]);

37        $fc_high[$i] = iconv("UTF-8", "EUC-KR", $fc_high[$i]);

38        $fc_icon[$i] = iconv("UTF-8", "EUC-KR", $fc_icon[$i]);

39        $fc_condition[$i] = iconv("UTF-8", "EUC-KR", $fc_condition[$i]);
40
41        echo "요일 : " . $fc_day_of_week[$i] . "<br>";

42        echo "최저온도 : " . $fc_low[$i] . "<br>";

43        echo "최고온도 : " . $fc_high[$i] . "<br>";

44        echo "아이콘 : " . $fc_icon[$i] . "<br>";

45        echo "날씨 : " . $fc_condition[$i] . "<br><br>";
46     }

47  }

48  ?> 


포인트는 29~33번 라인으로 배열형태로 되어 있는 corecast_conditions 정보를 루프를 통해 배열값이 저장하는 코드입니다.
나머지는 EUC-KR로 변환하고 출력하는 것으로 결과를 보면 다음과 같은 화면이 표시됩니다.

200902031503281.jpg 

현재 날씨정보와 앞으로 3일 동안의 예보를 화면에 뿌려주었습니다.
이제 이를 멋지게 화면에 뿌리는 것은 이제 개인의 몫이겠죠.
아마 구글 개인화 페이지처럼 표시하는 것이 그리 어렵지 않을 것으로 생각됩니다.

이렇게 해서 구글 날씨정보 API를 PHP를 통해 파싱하고 뿌려주는 것을 살펴보았습니다.
무척 간단하므로 많이 응용하셔서 재밌는 웹환경 만드시기 바라겠습니다.

function resize_iframe() { parent.document.getElementById(window.name).style.height = document.body.scrollHeight+20; } if ( self != top ) { if ( navigator.userAgent.indexOf("MSIE") != -1 ) {   document.body.onload = resize_iframe; //   document.body.onresize = resize_iframe; } else if ( navigator.userAgent.indexOf("Firefox") != -1 ) {   window.onload = new Function("parent.document.getElementById(window.name).style.height = '1000px'");   //window.onresize = new Function("parent.document.getElementById(window.name).style.height = document.body.scrollHeight+15");   } else {    window.onload = new Function("parent.document.getElementById(window.name).style.height = document.body.scrollHeight+15");    window.onresize = new Function("parent.document.getElementById(window.name).style.height = document.body.scrollHeight+15"); } } else { // If.... whole document needed... reload the document which includes iframe tag. } 

댓글목록

등록된 댓글이 없습니다.

PHP
871 (3/18P)

Search

Copyright © Cmd 명령어 18.116.23.59