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 앱에서는 잘못된 정보로 업데이트할 일이 없을 것이다.