안녕하세요. 난닝구입니다.
아주 오랫동안 눈팅만 하다가 급기야 포인트 욕심 때문에 몇자 적어봅니다.
다소 두서없는 팁일수 있습니다만 필요에 의해 해봤던 사이트 긁어오는 방법을 소개해 볼까합니다.
요즘같은 세상에 충분한 자본만 있으면 누가 긁어도 긁어주거나 아님 굳이 안 긁어도 먹고 살수 있을건데
하지만 목구멍이 포도청인지라..투자할 여력도 없고 그렇다고 밤새가며 일일이 정보를 카피해서 엑셀에다가
갖다 붙이는 고귀한 노동은 더더욱 하기는 그러하고...ㅠㅠ
혹시나 빵이나 그냥 한번 해보자는 마음으로 시도해봤습니다.
사이트 주인에게는 죄송하지만 다행이 원하는 정보를 쉽게 긁어올 수 있었습니다.
넘즈넷의 수집기도 같은 원리로 rss를 읽어서 데이타를 가공 저장하는 것입니다.
snoopy라는 소켓클래스를 이용하여 출력되는 페이지의 소스를 파싱후 원하는 정보만 쏙 뽑아서
디비에 저장하는 것인데 이것만 되어도 디비에 저장된 데이터만으로 많은 정보를 가공해 낼 수 있다고 생각합니다.
사실 snoopy를 이해하려면 객체라는 것을 선행해서 이해하여햐 합니다만..프로그래밍의 궁극이라..OTL
그냥 하라는대로 해보고 주제넘게 팁을 올려 봅니다.
각설하고..
APM이 설치된 호스팅 및 디렉토리에 snoopy 클래스 화일을 업로드하고 작업할 파일을 생성합니다.
include 'snoopy.class.php';
// 같은 디렉토리내에 어디든 해당 클래스를 읽어들여서 객체를 생성할 준비를 합니다.
// 객체를 생성한다는 것은 예를들어 snoopy로 한다면 페이지를 긁어와서 그것을 담을 그릇을 만든다고 생각하시면 됩니다.
//그릇에 담아서 내가 먹기 싫은건 요리조리 골라내고 먹고 싶은 것만 먹겠다는 뜻으로 생각하셔도 되겠습니다.
$sn = new snoopy;
//snoopy.class.php 를 편집기로 열면 클래스명이 나옵니다. 똑같은 이름으로 적어서 객체를 생성합니다.
//뭐 눈에는 보이지 않지만 그릇을 준비했을 것입니다.
$url = "긁어올 사이트주소를 넣습니다.";
$sn->fetch($url);
// 객체에 긁어올 주소가 이거다 라고 말해줍니다. fetch라는 명을 쓴거 보니 배열로 담은 것 같습니다.
$res = $sn->results;
//긁어서 만든 배열을 $res다가 담아주세요..라고 합니다.
//무슨짓을 어떻게 했는지 모르겠지만 사이트의 소스를 $res에 담아 놨을 겁니다.
//$sn-> 쓰임을 잘 보세요...ㅠ
$res = iconv("euc-kr","UTF-8",$res); //한글출력 때문에 긁어온 소스를 UTF-8로 변환합니다.
//한글! 세계최고의 언어답게 깐깐합니다. 하지만 마음을 비우고 읽어줘야 합니다.
//자..일단 원소스 $res는 잘려질? 준비가 끝났습니다.
//브라우저에서 페이지소스보기하고 머리속에 그 소스를 그려보세요..눈물납니다..막막합니다.
//본격적으로 칼질 들어갑니다.
$doma = explode("<!-- 자를 소스구분 -->"),$res); //explode를 이용해서 $res를 특정문자열로 구분하여 자릅니다.
// 따옴표안과 똑같은 문자열을 기준으로 칼질을 한다는 뜻입니다.
// AAAAAA<!-- 자를 소스구분 -->BBBBBBB<!-- 자를 소스구분 -->CCCCCCCC 이렇게 있다면
// <!-- 자를 소스구분 -->기준으로 자르면 $dama[0]=AAAAAA, $doma[1]=BBBBBBB,$doma[2]=CCCCCCCC 이렇게 들어갑니다.
// 배열 나왔습니다. 어쨋든 눈에 보이지는 않지만 자르면 $doma 의 내용은 잘려서 배열로 저장이 되어 있을 것입니다.
// 배열이 생성 되었을때 print_r($doma); 이렇게해서 보면 담긴 배열을 볼 수 있습니다.
// 사실 복잡한 소스를 배열로 담고봐도 막막합니다.
// 자를 예제 소스를 만들겠습니다.
aaaaaaaa<!-- 자를 소스구분 -->bbbbbbbb<!-- 자를 소스구분 -->cccccccc<!-- 자를 소스구분 -->
< span class="title" >< a href="./cut.php?no=1213" >가나다< /a >< /span >
< span class="title" >< a href="./cut.php?no=1214" >라마바< /a >< /span >
< span class="title" >< a href="./cut.php?no=1244" >사아자< /a >< /span >
< span class="title"> < a href="./cut.php?no=1278" >어쩌구< /a >< /span > ......
// 예제수준이 말이 아니네요..;;
// 잘 보시면 배열과 패턴이 보입니다. 패턴 나왔습니다.
// 알고보니 긁어오기의 핵심은 배열과 패턴(정규표현식을 알면 끝입니다ㅠ)이었습니다.
//자..다시 위의 예제로 칼질을 해보겠습니다. 긁어내야 할 정보는 "가나다", "라마바", "사아자", "어쩌구" ..입니다.
$doma = explode("<!-- 자를 소스구분 -->",$res);
// 요렇게 하면 $doma[3]에...
< span class="title" >< a href="./cut.php?no=1213" >가나다< /a >< /span >
< span class="title" >< a href="./cut.php?no=1214" >라마바< /a >< /span >
< span class="title" >< a href="./cut.php?no=1244" >사아자< /a >< /span >
< span class="title"> < a href="./cut.php?no=1278" >어쩌구< /a >< /span > ......
가 들어갑니다. 눈에 확 들어오나요?
// 요기까지하면 1차원 배열은 마스터했습니다. ;;
// 여기서 다시 패턴을 이용하여 잘라내려면 < span class="title" >을 기준으로 자르면 더 근접하게 됩니다.
// 자..여기서 잘린 $doma 중 $doma[0],$doma[1],$doma[2] 는 필요가 없죠?
// 그래서 아래 루프를 돌릴때 시작번호를 $i=3 으로 시작해서 0,1,2 때어버리고 $txt 변수에 다시 담습니다.
for($i=3;$i<$sizeof($doma);$i++) {
$txt = $doma[$i]; // $txt 는 순수하게 $doma[3]만 들어갑니다.$namePattern = "/\< a href\=\"\.\/cut\.php\?no\=(.*)?>(.*)?<\/a >/";// 일치하는 패턴을 정합니다. 패턴을 찾는 방법은 정규표현식을 사용하여 요령껏 사용합니다.// 여기서는 태그부분을 제외한 순수 텍스트만 가져와야 되므로// 고정된 부분은 매칭하고 "번호"와 뽑아낼 "텍스트"(가나다,라마바,...)는 변하고 있으므로 (.*)? 로 표현을 해줍니다.//preg_match($namePattern, $txt, $rest); // 지정한 패턴과 일치하는 부분을 $txt에서 찾아 $regs에 ???기준으로 배열을 만듭니다.$name .= $rest[2]."<br>";// 루프로 인해 값이 주욱 붙어서 나오기 때문에 태그로 개행했습니다.// 그런데 매칭후 $rest를 배열로 만드는 preg_match의 기준을 모르겠습니다 ㅠ// 암튼 배열의 순서를 체크해서 원하는 값이 출력되는 배열번호를 선택했습니다 ;;// 아마 기초가 너무 부족한 탓이라 생각됩니다.}
print_f($name); // 결과를 확인하실 수 있습니다.
루프가 돌때 나온 값을 디비나 아니면 다른 변수로 저장하여 체계적으로 만듭니다.
사실 기초가 부족한 탓으로 장시간을 헤맸으나 결과적으로 원하는 값을 얻게 되어서 만족했습니다.
앞서 말씀드렸다시피 핵심은 배열과 패턴인 것 같습니다.
페이지의 소스를 유심히 보시면 어떻게 나누어야 하겠다는게 보일 것입니다.
머리속에 그리시고 작업은 snoopy에게 맡기시고..디버깅을 수십차례하면서...
한번 시도해보는 것도 학습에 많은 도움이 되리라 생각듭니다.
제가 정보를 긁어온 사이트를 공개할 수는 없어서 예를 들어서 설명을 하긴했지만
또 어디 오류가 있을 수도 있을 것입니다. 이점 양해하시고..
사이트를 긁어온다는 것이 제법 흥미로운 것이며 동기부여를 할 수 있다고 생각했기에
허접한 팁을 올려 보았습니다. 조금이나마 도움이 되었으면 하는 바램입니다.
다음번엔 SUlinux 기반으로하여 스피디한 웹서버구축과 한방에 넘즈유틸 및 허브를
설치하는 과정에 대해 올려 볼 생각입니다.
감사합니다.