PHP로 작성된 강력한 외부 소켓 클래스인 스누피(Snoopy)클래스를 이용하면 웹사이트 내용을 쉽게 크롤링 해 올 수 있습니다. 제 경우에는 투자를 위해서 스누피 클래스를 사용하고 있습니다. 현재 주가를 실시간으로 긁어와서 제가 생각하는 목표 가격대와 괴리율이 얼마인지 한눈에 볼 수 있어서 편리합니다. 또 각 포털사이트와 신문사의 기사 중 관심 키워드가 포함된 신문 기사도 실시간으로 긁어와서 구독하고 있기 때문에 편리합니다.
스누피 클래스를 응용하는 방법은 많겠지만 오늘은 포털 사이트 다음에서 제공하는 실시간 주가를 크롤링해서 가져오는 방법을 간단하게 소개 드리겠습니다.
스누피 클래스 설치
스누피 클래스는 따로 설치할 필요없이 다운로드만 받아 프로젝트 내에 복사하면 됩니다. 스누피 클래스를 다운로드 받을 수 있는 주소는 다음과 같습니다.
다운로드 :
http://sourceforge.net/projects/snoopy/files/latest/download
다운로드를 받고 나서 압축을 풀면 Snoopy-1.2.4라는 폴더가 생깁니다. 이전 1.2.3버전에서는 구문 오류가 몇 군데 있었던 것 같은데 이번 버전에서는 고쳐진 것 같네요. Snoopy-1.2.4 디렉토리를 열어보면 아래와 같은 파일들이 있습니다.
스누피 클래스가 지원하는 기능이나 사용법에 대해서 궁금하신 부분이 있으면 README 파일을 읽어보시면 됩니다. 가장 핵심적인 파일은 Snoopy.class.php 파일 입니다. 저 파일을 우리가 만들고자 하는 프로젝트 내에 위치시키면 바로 사용할 수 있는 준비가 됩니다. 설치라고 할 것도 없네요. 이것으로 스누피 클래스가 준비되었습니다.
페이지 크롤링 테스트(네이버 메인 페이지 긁어오기)
그럼 스누피 클래스를 이용해서 웹페이지 하나를 테스트로 크롤링 해 보겠습니다. 일단 test.php 파일을 하나 생성해서 HTML의 <body>태그안에 다음과 같은 코드를 작성해 보았습니다.
1
2
3
4
5
|
include_once 'Snoopy.class.php' ; $snoopy = new snoopy; $txt = $snoopy ->results; print_r( $txt ); |
구글 블로그에서 Syntax Highligher를 쓰니 일부 구문이 깨지거나 왜곡 되네요. 감안하여 코드를 읽어주시면 감사 드리겠습니다.
스누피 클래스를 현재 프로젝트에 인클루드 하여(이 예제의 경우 스누피 클래스 파일이 동일한 폴더내에 있다고 가정), $snoopy에 새 객체를 만들어서 담았습니다. fetch 구문을 이용해서 네이버의 메인페이지를 모두 긁어오라고 구문 한 줄을 추가했고, 긁어온 구문은 $txt변수에 담아서 이를 print_r 해서 화면에 뿌려주는 간단한 구문입니다.
정말 너무너무 간단하고 강력합니다. 아래는 위 구문을 실행해서 네이버 메인페이지를 크롤링해서 긁어온 결과입니다. (스타일 시트는 당연히 안 긁어옵니다.)
원하는 부분만 가져오기 (주가만 긁어오기)
웹페이지 전체를 긁어오지 않고 원하는 부분만 가져올 수 없을까요? 당연히 그것도 가능합니다. 아래 화면은 포털 사이트 다음에서 제공하는 주식 종목 정보 페이지 입니다.
'수출포장'이라는 종목 정보 페이지입니다. 이 종목 페이지 내용을 전부 긁어오고 싶은게 아니라, 현재가만 가져오려고 합니다. 그러려면 먼저 이 페이지의 URL을 알아야겠습니다.
다음 증권 종목 페이지 주소 :
http://stock.daum.net/item/main.daum?code=002200
주소에서 가장 마지막 숫자 6자리는 종목코드입니다. 이 예제에서는 종목코드 '002200'번 즉, 수출포장 종목의 시세를 가져오도록 하겠습니다.
현재가 부분을 가져 오려면 HTML DOM 구조를 파악해야 합니다. 해당 페이지 소스 보기를 하거나 개발자 도구를 이용해서 현재가 부분의 마크업을 살펴보도록 하겠습니다.
1
2
3
4
5
6
7
8
|
include_once 'Snoopy.class.php' ; $snoopy = new snoopy; $o = "" ; $txt = $snoopy ->results; $rex = "/\<em class=\"curPrice.+\"\>(.*)\<\/em\>/" ; preg_match_all( $rex , $txt , $o ); print_r( $o [0][0]); |
아까 네이버 메인 페이지 전체를 긁어온 코드를 조금 수정했습니다. fetch는 다음 증권 페이지 수출포장 종목을 바라 보도록 했습니다.
그리고 $rex 변수에 담기는 정규식을 잘 봐주세요. <em>태그에 curePrice라는 클래스를 가지고 있는 부분을 찾는 구문입니다. <em>~</em>태그 사이에 숫자만 뽑아와 $rex 변수에 담았습니다.
그리고 PHP의 정규 함수인 preg_match_all 함수에 이를 담아 정규식을 해석하고 print_r로 가져 온 가격 정보를 화면에 뿌려주는 간단한 코드입니다. 이 코드를 실행한 결과는 아래 화면과 같습니다.
1
2
3
4
5
6
7
8
9
|
// DB 연결 $connect = mysql_connect( "localhost" , "root" , "root" ) or die ("DB에 연결할 수 없습니다. "); mysql_query( 'set names utf8' ); mysql_select_db( "stocks" , $connect ); // 종목 목록 가져오기 $query = "SELECT*FROM list" ; $result =mysql_query( $query , $connect ); |
DB연결에 성공하고 종목 목록 정보를 가져 왔다면 while 문을 이용해서 종목 개수 즉, DB의 row 개수 만큼 반복을 돌립니다.
1
2
3
|
while ( $row =mysql_fetch_array( $result )) { // 여기에 크롤러와 크롤러에서 가져 온 마크업 정보를 뿌려주면 되겠죠. } |
그리고 while 문 안에,
1
2
3
4
5
6
7
8
9
10
11
12
|
include_once 'Snoopy.class.php' ; $snoopy = new snoopy; $o = "" ; $txt = $snoopy ->results; $rex = "/\<em class=\"curPrice.+\"\>(.*)\<\/em\>/" ; preg_match_all( $rex , $txt , $o ); <tr> <th>현재가</th> <td><? print_r( $o [0][0]); ?></td> </tr> |
이와 같은 식으로 코드가 들어가면 됩니다. snoopy 객체 fetch 하는 부분에서 다음 증권 URL 마지막 숫자 6자리는 종목 코드라고 했습니다. 위 예시 코드에서는 DB에서 종목코드를 저장할 때 필드명을 's_code'로 지정했기 때문에 .$row[s_code] 라고 받아오면 동적으로 처리가 가능합니다.
그리고 루프를 돌면서 <tr>태그를 한 줄씩 뿌려가며 가격 정보를 보여주겠죠. 간단하지만 강력한 스누피 클래스를 이용한 크롤링 방법에 대해서 알아보았습니다.
크롤링 시 주의 사항
이미 잘 알고 계시는 독자분들도 많으시겠지만, 크롤링을 할 때는 몇 가지 주의해야 할 사항들이 있습니다.
- 웹페이지의 디자인이 바뀌어 마크업 DOM구조가 바뀌면 크롤러 코드도 바꿔줘야 합니다. 혹시 크롤러가 제대로 페이지 내용을 크롤링 해오지 못하면 가장 먼저 긁어 올 대상 웹페이지의 디자인이 바뀌지 않았는지를 체크해야 합니다.
- 스크립트를 이용해서 크롤러가 매일 같은 시간에 지속적으로 대량의 트래픽을 발생시켜 크롤링을 한다면 내 서버쪽 IP가 차단돼 해당 사이트에 접속이 안 될수도 있습니다. 당연히 크롤링도 안되겠죠. 불규칙적 비정기적, 다양한 IP로 크롤링 하는 것이 편법이기는 하지만 안전합니다.
- 아예 서버에서 외부 크롤링을 막는 경우도 있으니 크롤링 하기 전 간단하게 테스트를 해봐야 합니다.
스누피 클래스
스누피클래스는 크롤러 이외에도 소켓 통신을 위한 다양한 기능을 지원하는데 이 부분에 대해서는 추후 시간이 나면 다시 설명드릴 수 있도록 하겠습니다. 간단한 프로그래밍으로 투자 효율을 높이시기 바랍니다
출처 : http://investor-js.blogspot.kr/2013/07/php.html
'# Script > PHP' 카테고리의 다른 글
curl를 이용한 다음 자동로그인 (0) | 2016.08.24 |
---|---|
PHP 주석제거 정규식 (0) | 2016.03.30 |
PHP: Require_once(): Unable To Allocate Memory For Pool Error and Solution (0) | 2016.03.15 |
[error]PHP 컴파일 과정에서 흔히 볼 수 있는 오류 메시지 해결 방법2 (0) | 2015.08.16 |
PHP 컴파일 과정에서 흔히 볼 수 있는 오류 메시지 해결 방법 (0) | 2015.08.16 |
안녕하세요. 이곳은 IT위주의 잡다한 정보를 올려두는 개인 블로그입니다.
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!