728x90

네이버 지식인에 문의된 대구와 부산의 날씨 정보 파싱 예제다.


<?php
include_once 'simple_html_dom.php';

$url = "https://weather.naver.com/rgn/cityWetrCity.nhn?cityRgnCd=CT001024"; // 용인
$url1 = "https://weather.naver.com/rgn/cityWetrCity.nhn?cityRgnCd=CT007007"; // 대구
$url2 = "https://weather.naver.com/rgn/cityWetrCity.nhn?cityRgnCd=CT008008"; // 부산

$R = weather_parse($url1);
$S = weather_parse($url2);
echo json_encode(array("Time1"=>$R[0], "Weather1"=>$R[1],"Finedust1"=>$R[2],"Time2"=>$S[0], "Weather2"=>$S[1],"Finedust2"=>$S[2])); // 대구와 부산 날씨 정보

function weather_parse($url){
    $str = file_get_contents_curl($url);
    $enc = mb_detect_encoding($str, array('EUC-KR', 'UTF-8', 'shift_jis', 'CN-GB'));
    if ($enc != 'UTF-8') {
        $str = iconv($enc, 'UTF-8', $str);
    }

    $html = new simple_html_dom(); // Create a DOM object
    $html->load($str); // Load HTML from a string

    $R = array();
    $item = $html->find('div[class=c_tit2]',0)->find('em',0)->plaintext;
    array_push($R,$item);
    $item = $html->find('div[class=w_now2]',0)->find('em',0)->plaintext;
    array_push($R,$item);
    $item = $html->find('div[class=w_now2]',0)->find('em',1)->plaintext;
    array_push($R,$item);
    return $R;
}

function file_get_contents_curl($url) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // https 일때 이 한줄 추가 필요
    $data = curl_exec($ch);
    curl_close($ch);
    return $data;
}
?>


파일에 대한 설명은 https://link2me.tistory.com/1603 참조하라.


블로그 이미지

Link2Me

,
728x90

PHP Simple HTML DOM Parser 를 활용하여 네이버 날씨정보를 파싱하는 방법이다.


준비물

http://simplehtmldom.sourceforge.net/ 에서 파일을 다운로드하고 simple_html_dom.php 를 include 한다.

다운로드 받은 파일에 포함된 예제는 읽어보거나, 구글링해서 사용법에 대한 예제를 찾아보면 된다.


<?php
include_once 'simple_html_dom.php';
function file_get_contents_curl($url) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // https 일때 이 한줄 추가 필요
    //Set curl to return the data instead of printing it to the browser.
    $data = curl_exec($ch);
    curl_close($ch);
    return $data;
}

?> 


그럼 2단계로 파싱할 곳을 선택한다.

내가 사는 지역인 용인지역을 파싱할 곳으로 선택하고, 네이버 날씨정보 URL을 알아낸다.


$url = "https://weather.naver.com/rgn/cityWetrCity.nhn?cityRgnCd=CT001024";


$str = file_get_contents_curl($url);
$enc = mb_detect_encoding($str, array('EUC-KR', 'UTF-8', 'shift_jis', 'CN-GB'));
if ($enc != 'UTF-8') {
    $str = iconv($enc, 'UTF-8', $str);
}

print_r($str);


여기까지 하면 날씨정보에 대한 소스보기를 할 수 있다.

마우스 우클릭하여 소스보기를 하면 소스 정보가 나온다.

소스에서 파싱할 곳을 찾아내야 한다.


소스보기에 아래 그림을 찾아낼 수 있다.

<em>태그안에 있는 정보가 파싱할 정보라는 걸 확인할 수 있다.


그럼 이제 simple_html_dom 파싱 처리를 위한 단계로 코드를 구현하자.

// Create a DOM object
$html = new simple_html_dom();
// Load HTML from a string
$html->load($str);


<em> 태그를 파싱하는 방법은 아래와 같이 하면 모든 em 태그를 찾아준다.

foreach($html->find('em') as $element){
    echo $element->innertext . '<br>';
}


시간정보만 파싱해보자.

foreach($html->find('div[class=c_tit2]',0)->find('em') as $element){
    echo $element->innertext . '<br>';
}
와 같이하면 시간정보만 파싱되는 걸 확인된다.

$html->find('div[class=c_tit2]',0) 와 같이 0을 넣어주어야 하는 거 잊지말자. 소스와 비교하여 확인하면 된다.

find는 선택한 태크를 찾고 그 자식들을 모두 찾는데 다시 find 로 em 태크를 선택한 것이다.

육안으로 확인하면 하나 밖에 없다는 것을 알 수 있으므로

$time = $html->find('div[class=c_tit2]',0)->find('em');

를 하면 Trying to get property of non-object라고 하면서 에러가 발생한다.

$item = $html->find('div[class=c_tit2]',0)->find('em',0); 라고 하면 에러가 발생하지 않는다.

echo $item->plaintext; 를 하면 시간 정보가 출력되는 걸 확인할 수 있다.

한번에 하면 $item = $html->find('div[class=c_tit2]',0)->find('em',0)->plaintext; 로 하면 된다.


원하는 결과만 뽑아내면

$R = array();
foreach($html->find('em') as $element){
    array_push($R,$element->innertext);
}
echo '시간 : '.$R[1].'<br />';
echo '날씨 : '.$R[2].'<br />';
echo '미세먼지 : '.$R[3].'<br />';


하나 하나 분리해서 코드를 작성해보면....

$item = $html->find('div[class=c_tit2]',0)->find('em',0)->plaintext;
echo $item.'<br />';

$item = $html->find('div[class=w_now2]',0)->find('em',0)->plaintext;
echo $item.'<br />';

$item = $html->find('div[class=w_now2]',0)->find('em',1)->plaintext;
echo $item.'<br />';


코드를 Android 에서 JSON 으로 파싱처리하도록 수정했다.

<?php
include_once 'simple_html_dom.php';
function file_get_contents_curl($url) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // https 일때 이 한줄 추가 필요
    //Set curl to return the data instead of printing it to the browser.
    $data = curl_exec($ch);
    curl_close($ch);
    return $data;
}

$url = "https://weather.naver.com/rgn/cityWetrCity.nhn?cityRgnCd=CT001024";

$str = file_get_contents_curl($url);
$enc = mb_detect_encoding($str, array('EUC-KR', 'UTF-8', 'shift_jis', 'CN-GB'));
if ($enc != 'UTF-8') {
    $str = iconv($enc, 'UTF-8', $str);
}

//print_r($str);

$html = new simple_html_dom(); // Create a DOM object
$html->load($str); // Load HTML from a string

$R = array();
foreach($html->find('em') as $element){
    array_push($R,$element->innertext);
}
$R[2] = preg_replace("(\<(/?[^\>]+)\>)", "", $R[2]); // html 태그를 없애는 정규식
echo json_encode(array("Time"=>$R[1], "Temperature"=>$R[2],"Fine dust"=>$R[3]));
?>


이렇게 하면 네이버 날씨정보 소스코드가 달라져도 이 PHP 파일만 수정해주면 되므로 Android 앱에서는 잘못된 정보로 업데이트할 일이 없을 것이다.


블로그 이미지

Link2Me

,