TIP게시판

제목 기상특보 가져오기
글쓴이 darkninja 작성시각 2014/07/07 19:43:50
댓글 : 4 추천 : 0 스크랩 : 0 조회수 : 15783   RSS
기상청저작권
http://web.kma.go.kr/global/footer/copyright.jsp
아래코드는 학습용도나 로컬에서만 사용하시고
실제 서비스에서는 
공개된 기상청API 를 사용하세요!
http://web.kma.go.kr/info_open/public_data/request.jsp
https://www.data.go.kr/#/L2NvbW0vY29tbW9uU2VhcmNoL29wZW5hcGkkQF4wMDIkQF5wYmxvbnNpcFJlc3JjZVBrPXVkZGk6YWY5MTQ3ZTktYWM5YS00NTI5LTkwZTAtOTRhYzQyN2Y5ZGE3JEBec2tpcFJvd3M9MCRAXm1heFJvd3M9MTA=
무단으로 훔쳐와서 사용하면 뒤끝이 우려되니
안전하게 등록하셔서 사용하세요!

이번에는 특정 사이트에서 글을 가져오는 연습입니다.
기상청 기상특보 페이지에서
http://www.kma.go.kr/weather/warning/status.jsp
dl class="special_report_list3"

이렇게 비슷하게 생긴 분을 모셔옵니다!

실제 검색패턴은
$pattern = '~]*)(class\\s*=\\s*["\']special_report_list[^>]*["\'])([^>]*)>(.*?)~sim';

이렇게 생겼는데 비슷한게 몇개 있어서
전부다 검색해서 제일 마지막거를 표시합니다!

정규식이 많이 등장하는데
자꾸 만지다 보면 조금씩 알아가는 문제점이 발생합니다.

기상청 사이트가 charset=euc-kr 로 되어있어서 
화면에 표시할려면 변환을 해야 합니다.
여러번 변환하면 꼬이는수가 있으니
가급적이면 적게 변환하는게 좋을거 같습니다!
$warning = get_warning();
echo $warning;
function get_warning() {
	$url = "http://www.kma.go.kr/weather/warning/status.jsp";
	$m = sprintf('d', ((int)((date("i"))/5))*5); //5분단위로 파일저장
	$file_sucess = "status-sucess.jsp";
	$file_name = "status".date("ymdH").$m.".jsp"; //status1407071205.jsp
	$file_path = 'J:/htdocs/htdocs-ci3/img/warning/';

	if (!is_file($file_path . $file_name)) { //5분 단위로 저장됨
		$data = file_get_contents($url); //기상특보 페이지 읽기
		if ($data === false) {
			$error = error_get_last();
			if ($error) {
				$error = explode(': ', $error['message']);
				$error = trim($error[2]) . PHP_EOL;
				fprintf(STDERR, 'Error: '. $error);
			}
			$data = file_get_contents($file_path . $file_sucess); //읽기실패시 서버저장파일 사용
		} else {
			$data = str_replace("\t", ' ', $data); //탭 없애기
			$data = preg_replace('/^\n+|^[\t\s]*\n+/m', '', $data); //공백라인 없애기

			$fp = fopen($file_path.$file_name, "w"); //서버에 파일 저장
			fwrite($fp, $data);
			fclose($fp);
		}
	} else { //5분이 지나지 않았으면
		$data = file_get_contents($file_path . $file_name); //서버에 저장된 파일사용
	}	

	//$data = "";
	
	//정보추출에 사용될 패턴
	$pattern = '~]*)(class\\s*=\\s*["\']special_report_list[^>]*["\'])([^>]*)>(.*?)~sim';
	preg_match_all($pattern, $data, $matches);

	//기상특보가 있으면
	if (isset($matches) && isset($matches[0]) && isset($matches[0][3])) {
		if (!is_file($file_path . $file_sucess) || //마지막 성공한 파일이 없으면
		   (sha1_file($file_path . $file_sucess) !== sha1_file($file_path.$file_name))) { //새로운 기상특보가 발표됨?
			$fp = fopen($file_path . $file_sucess, "w"); //저장
			fwrite($fp, $data);
			fclose($fp);
		}	
		return iconv("EUC-KR", "UTF-8", $matches[0][3]);
	} else { //발표된 기상특보가 없으면 
		if (is_file($file_path . $file_sucess)) { //마지막으로 발표된거 사용
			$data = file_get_contents($file_path . $file_sucess);
			preg_match_all($pattern, $data, $matches);
			if (isset($matches) && isset($matches[0]) && isset($matches[0][3])) {
				//echo 'data local file use!
';
				return "서버에 저장된 정보가 사용되었습니다 ! 
".iconv("EUC-KR", "UTF-8", $matches[0][3]);
			} else { //기상특보가 없슴,,,뭔가 잘못됨!!!
				return "기상특보가 없습니다 !";
			}	
		} else { //마지막 성공 없슴
			return "기상특보가 없습니다 !";
		}
	}	
}	
 다음글 넷빈즈 8.0 CI 자동완성 기능 쉽게 하기 (2)
 이전글 모바일 여부를 체크할 수 있는 멋진 걸 발견했습니다~ (5)

댓글

darkninja / 2014/07/07 23:10:36 / 추천 0
http://www.kma.go.kr/weather/forecast/summary.jsp
특보페이지는 기상정보가 있다가 사라집니다.
이페이지가 좀더 나아 보이는군요!
아래 패턴으로 추출하시면 됩니다!
 
    $pattern = '~<table([^>]*)(class\\s*=\\s*["\']table_announcementtime[^>]*["\'])([^>]*)>(.*?)</table>~sim';

​        $temp_arr = array();
        $temp_arr[] = iconv("EUC-KR", "UTF-8", $matches[0][0]);
        $temp_arr[] = iconv("EUC-KR", "UTF-8", $matches[0][1]);
        $temp_arr[] = iconv("EUC-KR", "UTF-8", $matches[0][2]);
        return $temp_arr;
 
 <div class="row">
  <div class="col-sm-12">
   <div class="panel panel-info">
    <div class="panel-heading">오늘의 예보요약</div>
    <div class="mainbox-outer-wrapper">
     <div class="mainbox-inner-wrapper">
      <?php echo $summary[0]; ?>
     </div>
     <div class="mainbox-inner-wrapper">
      <?php echo $summary[1]; ?>
     </div>
     <div class="mainbox-inner-wrapper">
      <?php echo $summary[2]; ?>
     </div>
    </div>
   </div>
  </div>
 </div>
 <div class="row">
  <div class="col-sm-12">
   <div class="panel panel-info">
    <div class="panel-heading">오늘의 기상특보</div>
    <div class="mainbox-outer-wrapper">
     <div class="mainbox-inner-wrapper">
      <?php echo $warning; ?>
     </div>
    </div>
   </div>
  </div>
 </div>
한대승(불의회상) / 2014/07/10 10:50:25 / 추천 0
좋은 정보 감사 합니다.
덕분에 일기예보에 관심을 갖게 되었습니다. ^^
코드이그 / 2014/08/05 16:49:46 / 추천 0
좋은정보 감사드립니다.

공부에 도움이 될거 같아요 ㅎㅎ
darkninja / 2014/08/05 17:28:30 / 추천 0
$content = file_get_contents($url'); <= 이게 안될때
$content = getURLPage($url); <= 이걸 사용 하세요^^
function getURLPage($url) { 

    //$url = 'http://username:password@hostname:80/path?arg=value#anchor';
    //Array (
    //[scheme] => http
    //[host] => hostname
    //[port] => 80
    //[user] => username
    //[pass] => password
    //[path] => /path[removed]void(0)
    //[query] => arg=value
    //[fragment] => anchor
    //)

 $tmp = parse_url($url);
 if(!$tmp || $tmp['scheme'] != "http") return 0; 

 $host = $tmp['host']; 
 $port = (isset($tmp['port'])) ? $tmp['port'] : 80; 
 $path = (isset($tmp['path'])) ? $tmp['path'] : "/"; 
 $para = (isset($tmp['query'])) ? $tmp['query'] : ""; 
 
 $errno = 0;
    $errstr = '';

 $fp = @fsockopen($host, $port, $errno, $errstr, 10); 
 if(!$fp) {
  echo "error-http소켓접속에 실패하였습니다."; 
  return 0;
 }

 $header = "GET ".$path.'?'.$para." HTTP/1.0\r\n"; 
 $header .= "Host: ".$host."\r\n"; 
 $header .= "User-agent: PHP/HTTP_CLASS\r\n"; 
 $header .= "\r\n"; 
 fputs($fp,$header); 

 $ret = ''; 
 while(!feof($fp)) { 
  $ret .= fgets($fp, 1024); 
 } 

 fclose($fp); 
 return $ret ; 
}