BLOG ESPERANCA

사이트 긁어 오기 본문

Program/PHP

사이트 긁어 오기

yobuce 2011. 5. 2. 10:45

http://korcow.egloos.com/1889584



"사이트 긁어오기" 다른말로 사이트 파싱작업을 하는 이유는 단순하다. 노가다를 컴터에게 대신 시키기 위해서다. 로또번호를 일주일마다 입력하기 귀찮기 때문에 나눔로또 사이트에서 매주 로또 번호를 긁어온다. 경쟁사의 상품을 매번 찾아 볼 수가 없기 때문에 옥션을 주기적으로 긁어 온다.

사이트 긁어오기를 구현하기 위해서는 정규표현식이 필수다. 정규표현식을 몰라도 가능은 하다. 소스가 지저분해지고 나중에 수정하기면서 욕나오는 것만 빼면.. 정규표현식이라는 녀석이 간단해 보이지만 쓸 때마다 헤깔리고 잊어버린다. 그래서 사이트 긁어오는 방법을 간단히 정리해본다.


그전에 php에서 정규표현식을 사용하는 방법을 간단히 걸어 넘어가자. php에서 정규표현식을 쓰는 방법은 여러가지다. 개인적으로는 아래방법을 이용한다.

include 'class.snoopy.php';

$snoopy=new snoopy;

$snoopy->fetch("http://moonseller.net");

$txt=$snoopy->results;

$rex="/[0-9]{4}/";

preg_match_all($rex,$txt,$o);

print_r($o);

사실 사이트 긁어오기는 이게 전부다. 여기서 $rex로 시작하는 정규표현식을 어떻게 요리하는가가 관건이다.

일단 사이트를 긁어오는데는 snoopy 라는 사이트파싱 클래스를 이용한다. 간혹 호스팅에 보면 fopen 함수가 막혀있을때가 있다. fopen이 막혀있어도 curl 함수는 막아놓지 않는데, snoopy 클래스는 curl 함수를 편하게 사용 할 수 있게 해준다. 스누피 클래스에 대해서는 예전에 적은 글을 참조..

$txt에 사이트의 소스가 담겨졌다. 이 소스를 정규표현식을 이용해서 원하는 내용을 뽑아낸다. 예제에서는 숫자 4자리를 뽑아 내기로 되어 있다. [0-9]는 0에서 9까지 라는 의미이고 , {4}는 4자리라는 의미다.

preg_match_all 함수는 내용($txt)에서 정규표현식($rex)에 딱 맞는 녀석들을 뽑아내서 배열($o)로 만들어준다. 여러함수 써봤는데 이 함수가 제일 쓰지 편했다.

결과값으로 나온 배열을 DB에 넣던 TXT로 저장하든 화면에 뿌려주던 .. 그건 알아서 하시고.. 사이트 긁어오기에 유용한 정규표현식 몇가지를 보자.

전화번호만 뽑아내기

$rex="/[0-9]{3}-[0-9]{4}-[0-9]{4}/"

이메일만 뽑아내기
요즘엔 이런식으로 이메일 수집을 못하게 이미지로 처리하는 경우가 많다.

$rex="/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*$/";

특정태그로 둘러 쌓인 내용만 뽑아내기

이 녀석이 핵심이다. 보통 영어로만 된 경우에는 [A-Za-z]* 라고 하면 되는데, 한글일 경우 참으로 애매해진다. 그럴때 아래와 같은 꽁수(?)를 쓴다.

$rex="/\<span id=\"moonseller\"\>[>^]\<\/span\>/";

이정도만 하면 왠만한 사이트들은 다 긁어 올수 있다. 좀 더 알고 싶으면 아래 링크들을 참조하자.



php에서 특정 사이트를 긁어올때는 file 함수나 fopen 함수를 쓰면 된다. 왠만한 사이트는 file 함수로 접근을 할경우 가져가지 못하게 막아놓는다. 그런 사이트들를 긁어오려면 "snoopy" 라는 php class 를 이용한다.

snoopy는 php에서 소켓을 쉽게 쓸수 있는 강력한 클래스이다. 단순히 사이트를 긁어오는 기능과 더불어 html 태그를 쏙 빼고 텍스트만 긁어올수도 있으며, form 으로 바로 submit 해서 결과값을 받을수 있는 유용한 클래스이다.

    /(
//\\
// )_.-"""-._,-""-.
\\ ^,'_\ /_\ )
`./ /O\| |/O\\ /
\ \_/| |\_/ \_/
\ .' _ `. /
.-. ( .:(_):. ) ,-.
( `._`._.-._,'_,' )
) (
( .-------------. ) hjw
`-' `-'

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


본격적으로 snoopy를 이용해서 나눔로또 페이지를 긁어보자.


  1. 먼저 snoopy 클래스를 만든다
  2. include_once 'class.snoopy.php';
    $snoopy = new snoopy;

  3. 나눔로또 당첨번호 안내 페이지 주소를 긁어온다.

    $kai 는 회차를 나타낸다.
  4. $getUrl = "http://www.645lotto.net/result/guide_win_number.asp?sltSeq=".$kai;

    $snoopy->fetch($getUrl);

  5. 번호부분의 패턴을 분석해서 번호만 빼온다.
  6. $pattern='/img src="..\/images\/result\/ball[0-9]*.gif/';
    preg_match_all($pattern,$snoopy->results,$out);
    for($i=0;$i<=6;$i++){
    $num[$i]=str_replace(".gif","",str_replace('img src="../images/result/ball',"",$out[0][$i]));
    }

여기서 $num[0]~$num[5] 는 로또번호고, $num[6]은 보너스번호다.

소스 전체는 아래와 같다.

include_once 'class.snoopy.php';
$snoopy = new snoopy;
$getUrl = "http://www.645lotto.net/result/guide_win_number.asp?sltSeq=".$kai;
$snoopy->fetch($getUrl);
$pattern='/img src="..\/images\/result\/ball[0-9]*.gif/';
preg_match_all($pattern,$snoopy->results,$out);
for($i=0;$i<=6;$i++){
$num[$i]=str_replace(".gif","",str_replace('img src="../images/result/ball',"",$out[0][$i]));
}

이렇게 긁어온 번호들을 디비로 넣으면 모든 작업은 끝이다. 이 프로그램을 토요일 밤에 한번씩 돌려주면 최신 로또번호를 가져올수가 있다. 토요일밤마다 돌려주기 귀찮으면 crontab 이나 스케줄러를 쓰면 되는데 보통 cafe24같은 호스팅에서는 지원해주지 않는다.

그래서 내가 쓰는 꽁수는 feedburner 를 이용하는것이다.

feedburner를 이용한 주기적인 프로그램 실행(crontab 대용)


이정도 작업을 하고 나서 손털면 매주 자동으로 로또번호들이 자기의 디비에 차곡 차곡 쌓인다.뱀로또(http://bemlotto.com/) 에 이번회차 당첨번호 부분이 이렇게 만들어지고 있다.


물론 나눔로또 사이트의 디자인이 바뀌어 버릴때는 문제가 생긴다. 이럴때는 거기가 맞게 다시 패턴을 분석해서 적용해줘야한다. 예전에는 국민은행페이지에서 가져왔는데 사업자가 나눔로또로 바뀌면서 한동안 로또번호를 가져오지 못한적이 있었다. 지금은 수정해서 잘 가져오고 있다.

그리고 사이트를 긁어오는부분은 신중을 기해야한다. 너무 과도하게 긁어오는 행위는 법에 저촉되기 때문이다. 얼마전에 취업정보사이트에서 사이트를 긁어서 그대로 자기홈페이지에 제공한 사람이 3000만원에 합의를 봤다는 기사도 있었다. 물론 그 사람이 너무 과하게 한 부분이 있었겠지만 그래도 조심해야하지 않을까 한다.


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

[강좌] 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) 미흡한 실력이지만 메일로 질문을 해주신 분께 감사드립니다.~ ^^

사이트 긁는데 관심이 많거나 궁금한점 있으시면 언제든지 메일주시고, 사이트 긁는 작업이 필요하시면 아주~ 저렴한 가격에 긁어드리니 메일 주세요~



로또번호를 긁어오는것에 이어 이번엔 다음 메인 뉴스를 긁어보자.

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

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


다음은 file,fopen 함수를 사용하면 긁어올수가 없다. 접근을 못하게 막아놓은것같다. 하지만 우리에겐 강력한 snoopy가 있다. 스누피야 달려가서 다음물어오렴~


기본적인 방법은 로또번호를 긁어올때랑 똑같다. 다른점은 뉴스부분만 떼내는 작업이다.

먼저 아래와같이 다음의 메인 페이지를 가져온다.

include '_lib/class.snoopy.php';
$snoopy=new snoopy;
$snoopy->fetch("http://www.daum.net");

다음의 메인페이지에서 소스보기를 해서 , 뉴스가 시작하는 부분과 끝나는 부분이 어떻게 되는지 잘 살펴본다. 다른 부분과 구별이 될수 있는 요소를 찾아내야한다.

현재 다음메인의 뉴스는 위와 같다. 소스보기를 해서 잘보면 뉴스부분이 <!-- // schWrap --> 로 시작해서 <!-- // ctsWrap --> 로 끝나는것을 발견할수 있다. 즉, <!-- // schWrap --> 이 윗부분을 없애고 , <!-- // ctsWrap --> 아래부분을 없애면 뉴스만 남게 된다는 말이다.

$t=explode("<!-- // ctsWrap -->",$snoopy->results);
$r=explode("<!-- // schWrap -->",$t[0]);

이로써 $r에는 뉴스만 남게 되었다.

echo $r;

을 해보면 뉴스가 나오는것을 확인할수 있다.

전체 소스는 아래와같다.

<?
include '_lib/class.snoopy.php';
$snoopy=new snoopy;
$snoopy->fetch("http://www.daum.net");

$t=explode("<!-- // ctsWrap -->",$snoopy->results);
$r=explode("<!-- // schWrap -->",$t[0]);

echo $r[1];
?>

그런데 프로그램을 실행시켜보면 , 다음처럼 이쁘게 나오는것이 아니라 그냥 쭉 뿌려주는 모양으로 나온다. 이것은 다음의 CSS가 적용이 안된 상태이기 때문이다. 다음 페이지의 소스보기를 해서 CSS 부분을 붙여 넣어줘야 한다. CSS 부분과 더불어 javascript 부분도 같이 넣어줘야한다. 그래야 다음메인 뉴스와 똑같은 모양으로 볼수가 있다. 하지만 , 오히려 저렇게 나오는게 써먹기에는 더 좋을수도 있다. CSS만 만들어서 붙인다면 다음과는 완전히 다른 모양으로 뉴스를 보여줄수 있기 때문이다.

여튼 위와 같은 간단한 방법으로 네이버뉴스,네이트뉴스도 가져오는게 가능하다. 기술적으로는 가능하지만 법적으로는 문제가 될 소지가 많다 .따라서 너무 과도한 사용은 자제하는게 좋을것같다.


원하시는 사이트에서 원하는 내용만 긁어 드립니다.
파격적인 가격 !! 페이지당 5만원

원하시는 사이트에서 원하는 내용만 주기적으로 긁어서 db에 넣어드리거나 rss로 만들어 드립니다. FTP만 열어 주시면 됩니다. 작업기간은 사이트 난이도에 따라서 가격이나 시간은 차이가 날수 있습니다.
원하시는 분은 으로 메일 주세요~ ^^ 좀 도와주십쇼


왜 그동안 삽질을 하고 있었던걸까?
일반 호스팅에서는 외부에 있는 파일을 file,fopen으로 가져오는것을 막아 놨다. 그래서 꽁수로 python을 쓰고 있었다.

그.런.데. 당연히 안될거라 생각했던 fsocket은 된다. -_-;
난 왜 저걸 하고싶어서 파이썬 책을 두권이나 샀던걸까 ..

    /(
//\\
// )_.-"""-._,-""-.
\\ ^,'_\ /_\ )
`./ /O\| |/O\\ /
\ \_/| |\_/ \_/
\ .' _ `. /
.-. ( .:(_):. ) ,-.
( `._`._.-._,'_,' )
) (
( .-------------. ) hjw
`-' `-'
여튼 snoopy 라는 강력하면서 쉬운 php용 소켓 클래스를 소개한다.
마지막 버전은 http://snoopy.sourceforge.net/ 에서 구할수 있다.
하지만 .. 지금 현재 마지막 버전인 snoopy 1.2.3 는 구문 오류가 난다.
snoopy 1.2.3 버전 구문오류 해결법
722번째 줄에서 구문오류가 날것이다. 722번째 줄을 보면 아래와 같다

"?,
"?,
"?,
"?,
"?,
"?,
"?,


이걸 아래와 같이 바꿔주면 된다.

"?",
"?",
"?",
"?",
"?",
"?",
"?",


아마도 어떤 특수 문자들 같은데 한글 윈도우에서는 보이지 않거나 깨져버린것같다.
그래서 ? 로 바뀌어버리면서 구문오류가 난것같다. (이유는 정확하지 않음)
일단 다운 받아서 원하는 디렉토리에 스누피를 넣어두시고 아래와 같이 사용하면 된다

include "Snoopy.class.php";

$snoopy = new Snoopy;

$snoopy->fetchtext(http://www.php.net/);

print $snoopy->results;

아 놀라워라.. 너무 쉽다.

이런것도 가능하다.

$submit_url = "http://lnk.ispi.net/texis/scripts/msearch/netsearch.html";

$submit_vars["q"] = "amiga";

$submit_vars["submit"] = "Search!"; $submit_vars["searchhost"] = "Altavista";

$snoopy->submit($submit_url,$submit_vars); print $snoopy->results;

저 주소로 쿼리를 보내서 결과값을 값는것이다. 이외에도 여러가지 기능들이 많다.
  • 웹사이트 내용을 긁어오기
  • html 태그는 쏙빼고 내용만 긁어오기
  • 링크만 골라서 가져오기
  • 프록시서버 지원
  • 기본적인 로그인인증 지원
  • 사용정보, 레퍼러, 쿠키등 설정 지원 (아.. 이거 위험한데..)
  • 쉽게 폼데이타를 보내고 결과값 받기 (이거도 위험한데..)
  • 프레임 지원

자세한건 README 파일(프로그램파일들안에있음) 참조

세상엔 없는게 없는거같다.


프로그래머로써 너무 편해지고 있다.
집안일이 힘들것같아서 세탁기며 청소기며 집안에 들여놔줬더니 더 게을러지는 주부같다고나 할까? ㅋㅋ
그럼.. 파이썬은 안녕~ 다음에 언제 또 필요해질지 모르겟지만 이제는 나에게 무용해졌구나.. 그동안 고생했어.


사이트를 긁어오기를 하다보면 fsockopen(): unable to connect to 라는 에러가 나면서 사이트 긁어오기가 되지 않는 경우가 종종있다. 특히 외국 사이트중에 그런 곳이 많다. 사이트를 방문하지 않고 내용만 쏙 빼가는게 탐탁치 않아서 막아 놓은경우도 있고, 국가적인 차원에서 차단을 시킨경우도 있다.

예를 들어 , 일본 최대 AV 회사중에 하나인 DMM은 한국에서 들어오는 방문자를 차단시켜놓았다. 실제로 AV를 구매하지도 않으면서 트래픽은 엄청나게 잡아 먹기 때문이다. 또 다른예로 , 미국 국가 기관들중에는 미국에서 접속하지 않으면 페이지에 접근할수도 없는곳들이 있다. 재미있는건 웹브라우져를 열어서 보면 열리는데, 스누피로 긁어올려고 하면 안된다는 점이다.

현재 내가 발견한 사이트 긁어오기가 안되는 사이트의 유형은 세가지다. 세션을 물고 들어가야지만 페이지가 열리는 경우와 자기 자신의 도메인에서 오지 않을 경우 정상적인 접근이 아니라고 하는 경우 , 그리고 특정 국가의 아이피를 아예 차단시킨경우다.

1. 세션을 물고 들어가야 하는 경우

이 경우는 사이트 관리자가 임의로 막아놓은 경우다. 로봇이 아닌 사람이 직접 들어와야만 접근이 가능하게 하기 위해서다. 웹브라우져로 직접 주소를 클릭하고 들어와야만 페이지가 열린다. 이 경우에는 보통 세션을 임의로 먹여서 차단하는데.. 스누피에서 세션을 강제로 먹여주면 된다.

사용법은 간단하다. 스누피 fetch 하기전에 아래와 같이 세션값을 임의로 먹여준다.


$snoopy->cookies["SessionID"] = 세션값;

물론, 사이트에서 사용하는 세션변수를 찾아내야한다. 사실 세션변수라기 보다 쿠키값이다. 자바스크립트로 생성해서 쓰는 경우가 많기 때문에 사이트의 소스를 면밀히 관찰하면 대충 세션변수와 넣어야하는 값을 알아 낼 수가 있었다. 불가능한 경우도 있지만 내 경험상 왠만한곳은 다 가능했다.

2. 자기 자신의 도메인으로 부터 들어오지 않으면 막아버리는 경우

보통 페이지가 아이프레임으로 구성된경우 이런 경우가 많았다. 아마도 외부에서 아이프레임안의 내용만 링크해서 가져가지 못하도록 하기 위해서가 아닌가 한다.

위와 마찬가지로 fetch 하기전에 아래와 같이 값을 먹여준다.

$snoopy->referer = “접속한 도메인";

이 방법은 자기가 어디서 왔는지 숨길때도 유용하다. 접속한 도메인을 naver.com으로 한다면, 상대방 로그기록에는 네이버에서 방문한것처럼 보일것이다.

3. 외국 사이트가 한국 ip를 아예 차단한 경우

우리나라 정부에서 차단할때도 있고 , 외국에서 한국을 차단할때도 있다. 두 경우다 우회경로를 통하면 접근할수 있다. 우회경로를 프록시라고 부른다. 바로 가는게 아니라 다른곳을 들렀다가 가는것이기 때문에 속도는 조금 느리다.

프록시서버들 중에 유료도 있고 무료도 있는데, 왠만한곳은 무료로 가능하다. 아래는 무료프록시 서버를 보여주는 사이트들이다.

http://nntime.com/proxy-country/United-States-01.htm

www.cybersyndrome.net/plr5.html

위 사이트들에서 좋은 프록시 서버를 찾았으면 아래와 같이 세팅해준다.

$snoopy->proxy_host = “프록시서버";
$snoopy->proxy_port = "프록시 서버 포트번호";

무료프록시를 쓰다보면 아래 에러가 뜰때가 있다.

You are trying to use a node of the CoDeeN CDN Network. Your IP address is not recognized as a valid PlanetLab address, so your request rate is being limited. ...

에러가 한번뜨면 같은 프록시로는 더 이상 접근이 안된다. 원인은 프록시서버가 결국은 트래픽을 토스해서 우리쪽으로 넘겨주는데, 너무 과도하게 토스를 시킬때 나는 에러다. 한마디로 너무 혹사를 시켜서 니 아이피와는 더이상 못해먹겠다는 것이다.

이럴때는 다른 프록시서버로 변경해주면 되지만, 매번 그럴수도 없는 노릇이다. 유료를 쓰거나 자동으로 무료프록시를 변경해주게 설정해줘야한다.

이상이다. 외국 사이트에서 주기적으로 자료를 받아와야하는 노가다가 있을때.. 위와 같은 방법으로 해봄직하다. 노가다는 컴퓨터에게 시키시고 자네는 영화나 한편 다운받아 보는게 어떠한가?