ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [PHP+snoopy] 옥션리스트 긁어오기와서 RSS 만들기
    파싱의 추억 2008. 9. 28. 10:30

    본 블로그에는 사이트의 내용을 긁어오는것에 대한 간단 강좌 시리즈가 있다.

    [강좌] php용 강력하면서 쉬운 소켓(socket)클래스 , Snoopy

    [php+snoopy] 나눔로또에서 로또번호 긁어오기

    그 글을 보고 이메일로 보내온 질문에 대한 답을 빙자한 간단 강좌다.

    아래는 메일 내용이다.

    ----------------------------------------------------------------------------

    저는 PHP파싱에 관심이 굉장히 많은사람인데요.

    님의 블로그를 보고 메일을 드립니다.

    초보입장에서 PHP스쿨에서 스누피를 알게되고 사용강좌를 찾다가

    님의 블로그에 간단한 예시들을 보고 궁금한점이 더 많아져서;;

    도저히 못참겠기에 메일 제목처럼 특정 페이지를 파싱해서 DB에 저장하고 RSS활용까지 문의를 드립니다. 아래 내용을 참고해 주세요.

    ★ 파싱 사이트 : http://www.auction.co.kr/

    (옥션 페이지 중에 판매자 상품만 나오는 페이지가 있습니다. 그 페이지를 파싱하는거죠)

    http://search.auction.co.kr/common/ItemList.aspx?frm=itempage&seller=momsfeel&pagesize=100&page=0

    파싱 양식은 아래 그림처럼 제품 1개당 1줄의 정보를 수집하여 저장합니다.

    ★ 파싱에서 텍스트는 큰문제가 아니지만 배송비 같은 부분등에서 간혹 이미지 이름을 기준으로 값을 유추해야 하는경우가 있습니다.

    내용을 보시고 가능여부를 알려 주시면 참고하겠습니다.

    어떤식으로 코드를 작성하면 좋을지 초보입장(개발공부중)에 너무 답답해서 메일을 드리는거라 개발을 님의 서버에 해두고 데이터만 전송하는 비공개 형태를 원하는게 아니랍니다.

    ----------------------------------------------------------------------------

    미력한 실력이지만 나름 분석해서 만들어보았다. 강좌는 사이트에서 소스를 가져와서 각 항목별로 배열을 생성하는것까지 설명한다. 생성된 배열을 디비에 넣거나 RSS로 만드는것은 PHP 기본에 해당하는 부분이기 때문에 생략한다.

    사용한 언어는 PHP 이고 , 긁어오기 위해서 SNOOPY CLASS 를 이용했다.

     [강좌] php용 강력하면서 쉬운 소켓(socket)클래스 , Snoopy

     

    스누피 클래스는 사이트의 소스를 가져오는역활을 한다. 하지만 진짜 쓸수 있는 자료로 분류하고 뽑아내는작업은 PHP에서 제공해주는 함수들과 정규표현식등을 적절히 사용하면 된다.

    자료를 분류하고 뽑아낼때 주로 쓰는 함수들은 다음과 같다.

    • preg_match,preg_match_all : 정규표현식에 매치된 글자들을 배열로 뽑아내준다. 특정 형태로 반복될때 사용하면 유용하다.
    • explode : 특정글자를 구분자로 분리해서 배열로 만들어준다. 쓸때없는 부분을 잘라내거나 정규표현식으로 짤라내기 애매할때 요령껏 사용한다.
    • strip_tags : 태그를 지우고 글자만 남긴다. 쓸데없는 태그를 지워 실제로 필요한 텍스트자료만 남긴다.
    • str_replace : 특정 글자를 원하는 글자로 바꿔준다.

    php를 해본 사람들이라면 익히 본 평범한 함수들이다. 이 함수들을 요령껏 쓰는게 중요하다.

    일단 소스는 아래와 같이 시작한다.

    include 'class.snoopy.php';
    $s=new snoopy;
    $url="http://search.auction.co.kr/common/ItemList.aspx?frm=itempage&seller=momsfeel&pagesize=100&page=0";
    $s->fetch($url);
    $txt=$s->results;
    $txt=iconv("euc-kr","UTF-8",$txt);

    스누피 클래스를 불러오고 객체를 생성시킨다음 원하는 주소를 긁어온다. 여기서 마지막에 iconv 를 사용해서 euc-kr 인코딩을 UTF-8로 바꿔준 이유는 나중에 정규표현식에서 한글을 뽑아내기 위해서다.

    $ex=explode("<!-- 물품이미지-->",$txt);

    이 부분이 중요하다. 코드로만 보면 <!-- 물품이미지--> 를 기준으로 $txt 내용을 잘라서 배열을 만들어 $ex 로 넣는다는 이야기다. 이렇게 하는 이유는 옥션 페이지 소스보기를 해서 유심히 쳐다보면 답이 있다.

    옥션의 각 물품들은 <!-- 물품이미지--> 를 기준으로 나뉘어져 있는것을 알수 있다. 즉 <!-- 물품이미지--> 를 기준으로 나누면 각 상품의 한줄 한줄을 배열로 넣을수 있다는 말이다.

    print_r($ex) 해서 배열리스트를 보면 더욱 명확히 이해가 될것이다.

    for($i=1;$i<sizeof($ex);$i++){
        $t=$ex[$i];
        //맨 마지막줄은 뒤에 꼬리가 붙어 있으니 떼버린다.
        if($i==sizeof($ex)-1){
            $ex2=explode("<!-- 미리보기 영역 -->",$ex[$i]);
            $t=$ex2[0];       
        }

    $ex는 for 문으로 돌려주는데 , 0부터 시작하는게 아니라 1부터 시작한다. 왜냐하면 0번 소스는 물품과는 상관없는 소스이기 때문이다. 마찬가지고 맨 마지막줄의 <!-- 미리보기 영역 --> 아래쪽도 쓸데없는 소스기 때문에 버려준다.

    이제 각 물품 한줄 한줄의 소스를 읽어서 필요한 항목만 쏙속 뽑아내면 된다. 여기에는 정답은 없다. 소스를 유심히 처다보면서 어떻게 하면 뽑아낼수 있을까 연구를 해보면 뽑아낼 방법이 보인다.

       $pattern="/type\=\"checkbox\" value\=\"[A-Z0-9]*\"/";
       preg_match($pattern, $t, $regs);
       $r[$i]['anum']=str_replace('"','',str_replace('type="checkbox" value="','',$regs[0]));

    먼저 옥션번호다. 소스를 유심히 보면 옥션글번호가 type="checkbox" value="A510633633" 에 나와 있는것을 알수 있다. 정규표현식을 이용해서 뽑아낸후에 쓸데없는 type="checkbox" value=" 부분을 날려버리면 옥션번호만 남게된다.

    이번호는 최종 결과 배열인 $r 에 넣어준다. 이런식으로 항목 하나하나를 배열에 넣어준다.

    $ex3=explode("<!-- 물품명 && Decoration-->",$t);
        $ex4=explode("<!-- 가격 -->",$ex3[1]);
        $subjectText=trim(strip_tags(str_replace("</span>","||",(str_replace("<span>","||",$ex4[0])))));
        //echo $subjectText;
        $subex=explode("||",$subjectText);
        $r[$i]['brand']=trim($subex[0]);
        $r[$i]['subject']=$subex[1];
        $r[$i]['adment']=trim($subex[2]);

        $ex5=explode("<!-- 할인-->",$ex4[1]);
        $priceText=trim(strip_tags(str_replace("</strong>","||",(str_replace("<strong>","||",$ex5[0])))));
        $pex=explode("||",$priceText);
        $r[$i]['price']=$pex[1];

    이 부분은 브랜드명,제목,광고멘트,가격을 뽑아서 배열에 넣어주는 부분이다. 그렇게 어려운 함수들이 아니니 소스를 보면 이해가 될것으로 생각된다.

    $ex6=explode("<!-- 배송-->",$ex5[1]);

        $ex7=explode("<!-- 구매자수 -->",$ex6[1]);
        $sendText=$ex7[0];
        $pattern="/([\xEA-\xED][\x80-\xBF]*)+/";
        preg_match_all($pattern, $sendText, $sendregs);
        for($xx=0;$xx<sizeof($sendregs[0]);$xx++){
            $r[$i]['send'].=$sendregs[0][$xx].",";
        }

    이부분은 배송방법에 대한부분이다. 배송방법부분을 자세히 보면 alt="무료반품" 이라고 된 부분이 있다. 배송방법부분에서 유일하게 한글이 적힌 부분이다. 즉, 한글만 뽑아내면 배송방법이 뽑을수 있다는 말이다.

    정규표현식을 이용해서 한글인부분만 모두 뽑아낸다.

    $ex8=explode("<!-- 판매자 -->",$ex7[1]);
        $sellText=trim(strip_tags($ex8[0]));
        $r[$i]['sell']=$sellText;

        $ex9=explode("<!-- 만족도&등급 및 구매버튼-->",$ex8[1]);
        $sellerText=$ex9[0];
        $pattern="/\<span\>[A-Za-z0-9]*\<\/span\>/";
        preg_match($pattern, $sellerText, $sellerregs);
        $r[$i]['seller']=strip_tags($sellerregs[0]);

    }
    print_r($r);

    http://keyword.web2r.net/auction.php 에 가면 뽑아진 결과를 볼 수 있다.

    판매한 수와 판매자 이름을 마지막으로 가볍게 뽑아내고 나면 끝이다. 사이트를 긁어오는것은 사이트 소스를 유심히 보는게 가장 중요하다. 아무리 유심히 봐도 안되는 사이트들이 분명있다.그래도 유심히 더 보면 길을 있다고 생각된다.

    사이트를 긁어와서 유용하고 올바른곳에 쓰면 좋지만 남의 컨텐츠를 무단으로 자기것인양 사용하는것은 자제해주길 바란다. 잡코리아 리스트를 그대로 가져다가 자기사이트인양 사용한 사람이 벌금문 경우도 있다.

    조심조심하는게 좋다. ~

     

    ps) 미흡한 실력이지만 메일로 질문을 해주신 분께 감사드립니다.~ ^^


    사이트 파싱에 궁금한점이나, 의뢰는  로 주세요 ^^




    댓글

달을파는아이 @ nalab.kr