사이트를 긁어오기를 하다보면 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. ...
에러가 한번뜨면 같은 프록시로는 더 이상 접근이 안된다. 원인은 프록시서버가 결국은 트래픽을 토스해서 우리쪽으로 넘겨주는데, 너무 과도하게 토스를 시킬때 나는 에러다. 한마디로 너무 혹사를 시켜서 니 아이피와는 더이상 못해먹겠다는 것이다.
이럴때는 다른 프록시서버로 변경해주면 되지만, 매번 그럴수도 없는 노릇이다. 유료를 쓰거나 자동으로 무료프록시를 변경해주게 설정해줘야한다.
"사이트 긁어오기" 다른말로 사이트 파싱작업을 하는 이유는 단순하다. 노가다를 컴터에게 대신 시키기 위해서다. 로또번호를 일주일마다 입력하기 귀찮기 때문에 나눔로또 사이트에서 매주 로또 번호를 긁어온다. 경쟁사의 상품을 매번 찾아 볼 수가 없기 때문에 옥션을 주기적으로 긁어 온다.
사이트 긁어오기를 구현하기 위해서는 정규표현식이 필수다. 정규표현식을 몰라도 가능은 하다. 소스가 지저분해지고 나중에 수정하기면서 욕나오는 것만 빼면.. 정규표현식이라는 녀석이 간단해 보이지만 쓸 때마다 헤깔리고 잊어버린다. 그래서 사이트 긁어오는 방법을 간단히 정리해본다.
그전에 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\>/";
이정도만 하면 왠만한 사이트들은 다 긁어 올수 있다.
사이트 파싱이라는 단어보다는 사이트 긁어오기라는 단어가 한국 사람에게는 혀에 감긴다. 사이트 긁어오기라는 단어가 주는 어감은 좀 그렇긴 하지만.. 사이트 파싱은 여러가지 긍정적인 활용이 가능하다. 사이트 긁어오기는 단순 노가다 반복작업을 대신해주면서 사람에게 시간을 벌어준다.
예전부터 달을파는아이 블로그에 사이트 긁어오기, 사이트 파싱에 관한 글들을 올렸다. 생각지 못하게 작업의뢰가 몇번 들어왔다. 작업의뢰는 내가 생각했던것보다 훨씬 다양했다. 생각지도 못한 곳에서 쓰일 수도 있음을 알았다. 몇일의 프로그램작업으로 한달이상 해야하는 노가다를 대신할 수도 있었고, 매일 매일 지겹게 반복되던 단순작업들이 사라지기도 했다.
기술적인 이야기는 놔두고, 활용사례를 소개하고자 한다.혹시나 매일 반복되는 노가다나 막막하기만 했던 사람들에게는 힌트가 될지도 모른다. 물론 사이트 이름과 구체적인 내용은 블라인드다.
#1 사이트 긁어오기로 쇼핑몰 상품 채우기
쇼핑몰이 하루에도 수십개씩 생기고 사라진다. 쇼핑몰이라는게 구축하기가 쉬워보이지만, 해야할일이 엄청나게 많다. 그 중에서 귀찮은일중에 하나가 상품채우기다. 보통은 운영자가 사진을 찍고, 내용을 정성스럽게 적어서 채워 넣는다.
의뢰자중에 한명이 해외사이트에서 상품을 수입해서 판매하는 쇼핑몰을 기획하고 있었다. 일종의 도매사이트를 끼고 쇼핑몰을 운영하는 형태인데, 도매사이트가 미국사이트라는 점이 다르다. 문제는 이 도매사이트가 수시로 바뀐다는 점이다. 재고가 항상 넘쳐나는게 아니다. 국내에서 주문을 받고 , 미국으로 오더를 내리면 상품이 없을때가 종종있다. 아주 곤란한경우다. 제품 자체가 사라지거나, 새 상품이 나왔는데 알아차리지 못하는 경우도 허다하다. 미국 사이트의 상품수가 워낙 방대해서 매일 매일 모니터링 하기가 여간 어려운게 아니다.
그래서 나에게 연락이 왔다. 이 미국사이트를 긁어서, 재고수와 새 상품을 알려 줄수 없는가? 매일 아침 직원 3명이서 사이트 전체를 둘러본다고 한다. 아침 시간을 전부 여기에 쏟아 붓기 때문에 여간 손해가 아니라고 한다. 그렇다고 안할수도 없는 일이고..
사이트 긁어오기를 이용해서 이 쇼핑몰을 매일 새벽에 긁는다. 상품리스트들을 모두 불어와서, 기존에 있는 상품인지 체크하고 .. 재고가 얼마나 있는지 업데이트 한다. 상품수가 1000여개라면, 하루 1000여번의 클릭와 웹페이지 보기가 사라졌다.
# 2. 쇼핑몰 이전 & 복사
쇼핑몰 운영하는 사람중에는, 분양을 하는 경우가 있다. 장사가 잘되는 사이트지만, 디자인만 달리 해서 오픈한다. 고객이 보기에는 운영자가 다른 두,세개의 사이트지만, 운영자는 한명이다. 세개의 사이트에서 주문이 들어오고, 운영자는 한번에 보내준다. 이렇게 하는 이유에 대한 설명은 뒤로하고, 구축의 애로점이 참으로 많다. 특히나 쇼핑몰 플랫폼이 달라지거나, 쇼핑몰 솔루션자체에 백업기능이 없는 경우 나감하기 그지 없다. 상품수가 몇개 안된다면 상관없지만, 100개,1000개이상되면 노가다가 장난아니다. 노가다를 해도 될만큼 효과를 보면 좋겟지만, 장사라는게 항상 효과가 있는건 아니다.
이때, 사이트 긁어오기가 쓰였다. 자기 쇼핑몰의 상품을 긁어다가 또 다른 자기 쇼핑몰로 상품을 옮긴다. 물론, 자동으로 이전하게 할수도 있다. 솔루션에 blogapi가 지원되거나, 자체 솔루션을 쓸경우다. 중간에 자동으로 올리는 프로그램을 넣어두면, 긁어다가 자동으로 올릴수도 있다. 하지만, 보통 쇼핑몰 솔류션은 그렇지 않다. 일단, 긁어온다음, 엑셀의 형태로 변환하고 , 쇼핑몰 관리자 모드에서 대량 업로드를 한다.
# 3. 고객 정보를 수집
이 부분은 상당히 민감하다. 이메일수집이 정보통신법에 위반되기 때문이다. 하지만, 이 부분을 증명하기가 여간 어려운게 아니다. 수집 플로그램의 존재만 숨긴다면, 사이트에서 직접 일일이 수작업으로 복사 붙여넣기를 했다고 하면 증거가 없다. 이 수집된 정보를 대량스팸이나 다른 악의적인 용도로 사용한다면 이야기는 달라지지만, 정상적인 영업을 위한 용도로 활용한다면 문제는 없지 않을까? 수집할수 있다는 기술적인 가능성과 그 수집된 정보를 써먹는건 분명히 다른 문제다.
자기 고객들이 많이 모이거나, 잠재고객들이 있는 사이트에서 원하는 정보를 긁을수가 있다. 의뢰로 공개된 개인정보는 넘쳐난다. 구글핵을 하지 않더라도, 구인구직사이트, 쇼핑몰, 물건매매 사이트등등. 이 모든 자료들을 수집하고 정리할수 있다.
#4. 내 수익이 얼마일까?
매번 확인해야 하지만, 상당히 귀찮은 일들이 있다. 개인적으로는 애드센스나 제휴사이트들의 수익확인이 그렇다. 애드센스만 운영한다면, 애드센스만 들락거리면 된다.사이트나 블로그를 운영하다보면 애드센스만 다는게 아니다. 보통 2,3개 많게는 수십개의 파트너사이트들으 함께 운영한다. 이 모든 사이트의 수익을 매번 로그인해서 확인한다는건 돈버는 재미를 반감시킨다.
사이트긁어오기를 하면, 이 모든 사이트들의 수익을 한번에 가져올수 있다. 가져온 정보를 sms나 이메일, 구글톡크같은 서비스와 연결할수도 있다 그러면, 일일이 페이지를 확인하지 않아도, 정해진 시간에 내 수익을 한눈에 받아 볼수도 있다.
#5. 로또번호 가져오기
로또번호를 가져오는 강좌는 예전에 했었다. 중요한건 로또를 이야기하고자 하는게 아니라 로또처럼 매주 확인해야하는 무언가를 가져올수 있다는 것이다. 자기가 원하는 방식으로 알림을 받을수 있다. #6번에 말할것처럼 rss로 만들어서, rss 리더로 읽을수도 있다. sms,이메일 원하는 방식으로 매주 로또 번호를 받아 볼수 있다.
#6. rss가 없는 사이트의 rss 만들기
블로그에는 기본적으로 rss 가 제공된다. rss 도 제공안되면서, 블로그 툴인척 했던 네이버가 있긴 있었지만.. 지금은 거의 모든 블로그툴들이 rss 를 제공한다. 블로그뿐만 아니라 제로보드xe도 기본적으로 rss를 제공한다.
툴제공과 무관하게, rss 공개여부는 블로그나 사이트 주인의 권한이다. 주인장 맘대로다. 아예 닫아 놓을수도 있고, 글의 앞대가리만 찔끔 내 보낼수도 있다. 이게 참 받아보는 입장에서는 답답할 노릇이다. 이때 사이트 긁어오기를 이용하면 , 글을 rss로 만들수 있다. rss형태로 만들고 나며, 편하게 rss리더로 받아 본다.
물론, 주인장이 원치않는 rss를 억지로 만들어서 혼자 받아보는것과.. 그 만들어진 rss를 공개해버리는것과는 또 다른 문제다.
기계의 할일은 기계에게
모든 사이트들이 보는 웹페이지뿐만 아니라, 정보제공용 xml 혹은 다른형태의 파일을 제공하면 구지 사이트 긁어오기 같은 일은 하지 않아도 된다. 요즘 만들어지는 사이트들은 기본적으로 rss가 제공되고 있어, 그 나마 낫다. 하지만, 이미 만들어진 혹은 적절한 정보제공이 없을 경우가 많다. 원하는 정보만 가져올수 있게 하는 사이트 긁어오기가 여전히 필요하다.
기계든 프로그램이든 사람 편하게 해야한다. 사람이 해야할 지루하고 반복적인 일들은 기계에 맞겨야한다. 복사 붙이기 복사 붙이기 복사 붙이기.. 먼가 하루종일 “내가 왜 이짓을하고있지?” 라는 생각이 드는 작업을 하고 있다면.. “혹시 기계에게 맞길수 있지 않을까?” 고 떠올려보자.
사이트 긁어오기를 하다보면, 로그인을 해야만 가능한 사이트들을 만나게 된다. 사이트파싱 에서 로그인처리는 까다로운 녀석인데, snoopy에는 로그인을 처리하는 기능이 있다. 로그인에 변수들을 던져주면 자동으로 로그인이 된다.
로그인 처리를 해보면, 대부분 스누피를 이용해서 파싱이 가능하다. 물론, 좀 복잡한 방법으로 해야만 하는 경우도 있다. 복잡한 방법은 놔두고, 간단히 처리하는 방법을 알아본다.
테스트로 사용할 사이트중에 어디가 좋을까나.. 제휴사이트중 “링크프라이스” 라는 곳으로 해보자. 보통의 사이트들은 아래 같은 방법이면 70%는 로그인이 가능하다.
일단, 사이트의 로그인처리를 살펴봐야한다. 알아야 할 항목은 크게 3가지다.
1. 로그인 처리를 하는 url
2. 아이디를 받아내는 변수
3. 비밀번호를 받아내는 변수
긁어올 사이트에 들어가서, HTML 소스보기를 한다. 로그인 폼 부분을 찾는다. 아래 부분이 로그인폼의 소스다.
<form name=“loginform” action=“https://www.linkprice.com/AC/login.php” method=“post” onSubmit=“change_login_type();”>
<p><input type=“radio” name=“login_target” value=“AC” checked class=“radio1”>
<input type=“radio” name=“login_target” value=“MC” class=“radio2”></p>
<input type=“text” size=16 maxlength=10 name=“account_id” value=“monody” class=“id”>
<input type=“password” size=16 name=“password” class=“pass”>
input type=“hidden” name=“from_www” value=“Y”>
<input type=“image” src=“image/btn_login.gif” class=“btn1” alt=‘로그인’>
<a href=“javascript:lost_password()”><img src=“image/btn_idfind.gif” alt=“아이디찾기” class=“btn2”></a>
<a href=“linkprice0801.htm”><img src=“image/btn_join.gif” alt=“회원가입” class=“btn3”></a>
</form>
<form> 태그의 action 값을 보면, 로그인 처리가 되는 URL을 확인할수 있다. 이 경우에는https://www.linkprice.com/AC/login.php 다. <input> 태그중 아이디를 넣는 칸의 name 값은 account_id 인것을 알수 있고, 비밀번호의 필드네임은 password 라는 것 을 알 수 있다.
필요한 중요요소 3가지를 모두 찾았다. 이 3가지요소를 가지고, 스누피에서 로그인 처리한다.
아래 소스가 로그인 처리하는 소스다.
include_once ‘class.snoopy.php’;
$__s=new snoopy;
$url=“http://www.linkprice.com/AC/login.php”;
$s[‘account_id’]=“내 아이디”;
$s[‘password’]=“내 비밀번호”;
$__s->submit($url,$s);
$__s->setcookies();
$__s->fetch(“http://www.linkprice.com/AC/index.htm”);
이렇게 기분좋게 간단히 로그인이 되면 참 좋겠지만, 간혹 마음대로 안되는 녀석들이 있다.
내가 이때까지 해본 애들중에 가장 어려운 녀석들 베스트 3.
- 쉐어박스 파트너 페이지
- 황금사주 관리자 페이지
- 카페24 리셀러페이지
로그인처리는 “아이디/비밀번호”가 들어가기때문에, 개인용이 아니면 쓰기가 어려운 경우가 많다.인터넷에서 은근히 귀찮은것이 로그인이다. 로그인해서 먼가를 주기적으로 확인해야할때, 로그인은 귀찮다. 이 기능을 이용하면 편안하게 원하는 데이타를 받아 볼 수 있다.
'자료창고' 카테고리의 다른 글
[yit서버 메모] node.js forever 플러그인 설치와 실행 (0) | 2014.10.16 |
---|---|
Ajax로 구현된 페이지네이션의 뒤로가기 이슈 (3) | 2013.04.24 |
JavaScript 코드를 가독성이 좋게 정리해줍니다 (0) | 2013.04.23 |
마인드맵 ASP (4) | 2013.04.22 |
참조할 PHP 소스 Dos PoC (0) | 2012.04.25 |