PHP 정규표현식을 이용해서 사이트 긁어보자 (노가다 없이 자료 수집하는 방법)

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

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


그전에 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\>/";

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

 


이 방법외에 xml 파싱하는 방법도 있다. xml 파싱으로 하면 좀더 쉽게 머리 안쓰고 긁어올수 있다. 문제는 긁어올 사이트가 완벽한 코딩이 되어 있어야 한다. xml이라는 녀석이 워낙 깐깐해서, 조금이라도 코딩을 잘못하면 에러를 토해낸다. 그래서 정규표현식을 이용하는 방법이 좀 더 안전하다.

항상 말하지만, 사이트 긁어오는 것은 약점이 있다. 사이트 디자인이 바뀌어 버리면 다시 정규표현식을 만들어야 한다. 그래서 자동으로 긁어오게 만들었다면, 사이트 디자인이 바뀌었을때를 대비해서 알림서비스가 필수다. 알림이 오면 즉시 소스를 수정해야한다.



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




Posted by 달을파는아이 달을파는아이

댓글을 달아주세요:: 네티켓은 기본, 스팸은 사절

  1. JS.Gooni
    2010.03.27 10:45 신고
    댓글 주소 수정/삭제 댓글
    컴터 프로그래밍은 잘 몰라서 하는 말인데..
    .
    .
    $rex="/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*$/";
    .
    .
    ↑ 설마 요런 무슨 공식 같은거 다 외우서 하는 거유??
  2. 소소한 일상1
    2010.03.27 15:36 신고
    댓글 주소 수정/삭제 댓글
    달님 안녕하세요. 에고 무슨 이야기인지 깜깜-컴맹의 비애 흑흑...

    며칠전에 제가 보낸 생뚱맞은 트랙백에 대해 해명하려구요. 혹시 놀라셨을까봐요. 제가 딱 일곱 분들께만 보낸 특별한 글입니다.^^

    제 작은 감사의 표현 + 컴퓨터 달인분들에 대한 희망사항이었어요.ㅎㅎ
    어떻게 하다보니 댓글도 남기지 않고 그냥 보내서 조금 죄송해서요. 그래도 다 이해하셨지요.ㅎㅎ

    오늘 하하가 드디어 오네요. 주말 멋지게 보내세요. 감사합니다.^^
  3. 2010.03.28 10:06 신고
    댓글 주소 수정/삭제 댓글
    유용한 서비스는 서비스 원작자가 유용하게 활용할 수 있는 Open API를 제공했으면 하는 바람이 있는데.
    아직 그런 분위기가 아닌 것이 아쉬움이 남기도 합니다.
  4. 2010.03.28 11:43
    댓글 주소 수정/삭제 댓글
    비밀댓글입니다
    • 2010.03.29 13:19 신고
      댓글 주소 수정/삭제
      답변감사감사~ ^^
      어제 하하 잼났어요. ㅋㅋ 우려를 표하는 분들도 있던데, 저는 새로운 재미를 줄 기대가 더 되네요.
  5. 2010.03.29 20:15 신고
    댓글 주소 수정/삭제 댓글
    전, 머리가 나빠서....외워서 하는데요....^^ ㅋㅋ
  6. secret
    2010.09.23 14:29 신고
    댓글 주소 수정/삭제 댓글
    영어의 압박. ㅜㅠㅠ
  7. 카르핀
    2010.10.19 16:49 신고
    댓글 주소 수정/삭제 댓글
    위에 소스를 어떻게 사용하는건지...?

    연락을 드리고 싶은데 연락처가 없네요..?

    혹시 도움주실 맘 있으시면 연락한번 부탁드릴게요..

    010-3168-2273 감사합니다..
  8. 2010.11.04 15:27 신고
    댓글 주소 수정/삭제 댓글
    안녕하세요...이번에 php파싱을 공부하다 님 싸이트 까지 들어오게 되었네요.. ㅎㅎ 좋은 정보 감사합니다.. 다름이 아니오라..한가지만 물어보고 싶어서 입니다..
    달을파는아이 님 의 방법대로 파싱을 해보니까요.. 예시에 나온 옥션상품은 이미지가 아~주 잘나오더라구요... 예시대루는 다 잘되던데요...
    문제는 제가 다른 사이트를 파싱해보니 이미지가 다 깨져서 나오는 거예요.. 깨진이미지소스 경로를 보니 제도메인 위치로 잡혀서..
    이미지가 다깨진거예요.. ㅜㅜ 이럴경우 해결방법좀 알려주시면 정말 감사하겠습니다.. 제가 아직 프로그램에 많이 서툴러서요;;;

    부탁드립니다...
  9. ㅇㅇ
    2012.04.19 03:42 신고
    댓글 주소 수정/삭제 댓글
    강좌 잘 봤습니다.
    snoopy로 구글도 긁을 수 있나요?
    curl로 긁으려고 했더니 막네요..차단됐음..
    $rex="/\<span id=\"moonseller\"\>[>^]\<\/span\>/";
    [^>] 이게 맞는듯 하네요.
  10. 2015.10.28 23:07
    댓글 주소 수정/삭제 댓글
    비밀댓글입니다


BLOG main image
멈추지 않으면 얼마나 천천히 가는지는 문제가 되지 않느니라 by 달을파는아이

나의 인생 시계 만들기 >>

카테고리

분류 전체보기 (429)
달을파는아이 (283)
머니머신 (125)
파싱의 추억 (20)
현미촌 현미국수면 (1)
Statistics Graph