크롤러 / 스크래퍼 만들면서 자주 만나는 문제. 대상 페이지가 Referer 헤더 없으면 메인으로 리다이렉트 해버리거나 본문을 숨기는 경우가 종종 있다. 이때 쓰는 꼼수들. CasperJS 1.1, PhantomJS 1.9 기준.
가장 단순한 건 fake link 태그를 만들어 DOM 에 붙이고 그걸 클릭하는 방법. 브라우저가 실제 "링크 클릭" 으로 인식해서 이전 페이지 URL 을 Referer 로 붙여 준다.
더 깔끔한 방법 — customHeaders 로 직접 Referer 박기
CasperJS 는 page 객체의 customHeaders 를 건드릴 수 있다. 이쪽이 코드가 반쯤 길이 줄어든다.
User-Agent 도 같이 바꾸는 게 보통
많은 사이트가 PhantomJS 기본 UA ("Mozilla/5.0 ... PhantomJS/1.9") 를 보고 로봇으로 판단해서 차단한다. 현실적인 값으로 바꿔 놓는 게 기본.
loadImages: false 는 대량 크롤링 시 효율 차이가 꽤 크다. 페이지 로딩 시간 30~50% 절감.
실제로 막히는 경우
- Referer 위조 방지: 쿠키 기반 세션 키로 교차 검증하는 사이트는 Referer 만 고친다고 안 먹힌다. 먼저 목록 페이지 열어서 쿠키 받고 → 상세 페이지로 들어가야 한다.
- CSRF 토큰: form 이나 ajax 쪽은 token 이 hidden 으로 심어져 있는 경우가 많음. 그걸 evaluate 로 긁어서 재사용.
- Cloudflare / reCAPTCHA: 이쪽까지 가면 PhantomJS 로는 벅차다. Selenium + real Chrome (Headless 이전) 또는 SlimerJS (Firefox 엔진) 로 우회 시도. 요새는 JavaScript 브라우저 검증 루틴이 많아서 PhantomJS 1.9 엔진 (WebKit 구버전) 만으로는 버거운 사이트가 늘고 있다.
수집은 가급적 정중하게
크롤링 윤리 문제도 있고, 잦은 접근은 IP 차단을 부른다. 개인 용도 / 내부 테스트에 한정해서 쓰자. 상용 수집이라면 해당 서비스가 제공하는 API 를 쓰거나 계약을 맺는 게 맞다. 특히 robots.txt 와 utilization 규정은 최소한 읽어 보는 것.
CasperJS 는 PhantomJS 2.0 이 나오면서 WebKit 신버전을 쓸 수 있게 된 덕에 점점 실용성이 높아지고 있다. 그래도 슬슬 Selenium WebDriver + Chrome 쪽으로 옮겨갈 준비를 하는 게 좋을 듯.
가장 단순한 건 fake link 태그를 만들어 DOM 에 붙이고 그걸 클릭하는 방법. 브라우저가 실제 "링크 클릭" 으로 인식해서 이전 페이지 URL 을 Referer 로 붙여 준다.
var fakeReferrer = "http://a.com";
var targetUrl = "http://b.com";
var casper = require('casper').create();
casper.start(fakeReferrer, function () {
this.echo(this.getCurrentUrl());
});
casper.then(function () {
// then 블록 안에서 evaluate 는 외부 변수에 직접 접근 안 됨 — 인자로 넘겨야 함
this.evaluate(function (url) {
var link = document.createElement('a');
link.setAttribute('href', url);
link.setAttribute('id', 'myTargetUrl');
document.body.appendChild(link);
}, targetUrl);
});
casper.then(function () {
this.click('a#myTargetUrl');
});
casper.run(function () {
this.echo(this.getCurrentUrl());
this.exit();
});
더 깔끔한 방법 — customHeaders 로 직접 Referer 박기
CasperJS 는 page 객체의 customHeaders 를 건드릴 수 있다. 이쪽이 코드가 반쯤 길이 줄어든다.
var fakeReferrer = "http://a.com";
var targetUrl = "http://b.com";
var casper = require('casper').create();
casper.start().then(function () {
this.page.customHeaders = {
"Referer": fakeReferrer
};
});
casper.thenOpen(targetUrl, function () {
this.echo(this.getCurrentUrl());
this.echo(this.getTitle());
});
casper.run();
User-Agent 도 같이 바꾸는 게 보통
많은 사이트가 PhantomJS 기본 UA ("Mozilla/5.0 ... PhantomJS/1.9") 를 보고 로봇으로 판단해서 차단한다. 현실적인 값으로 바꿔 놓는 게 기본.
var casper = require('casper').create({
pageSettings: {
userAgent: 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 ' +
'(KHTML, like Gecko) Chrome/43.0.2357.134 Safari/537.36',
loadImages: false, // 속도 + 트래픽 절약
loadPlugins: false
}
});
casper.start().then(function () {
this.page.customHeaders = {
'Referer': 'http://example.com/search?q=foo',
'Accept-Language': 'ko-KR,ko;q=0.9,en;q=0.8'
};
});
loadImages: false 는 대량 크롤링 시 효율 차이가 꽤 크다. 페이지 로딩 시간 30~50% 절감.
실제로 막히는 경우
- Referer 위조 방지: 쿠키 기반 세션 키로 교차 검증하는 사이트는 Referer 만 고친다고 안 먹힌다. 먼저 목록 페이지 열어서 쿠키 받고 → 상세 페이지로 들어가야 한다.
- CSRF 토큰: form 이나 ajax 쪽은 token 이 hidden 으로 심어져 있는 경우가 많음. 그걸 evaluate 로 긁어서 재사용.
- Cloudflare / reCAPTCHA: 이쪽까지 가면 PhantomJS 로는 벅차다. Selenium + real Chrome (Headless 이전) 또는 SlimerJS (Firefox 엔진) 로 우회 시도. 요새는 JavaScript 브라우저 검증 루틴이 많아서 PhantomJS 1.9 엔진 (WebKit 구버전) 만으로는 버거운 사이트가 늘고 있다.
수집은 가급적 정중하게
크롤링 윤리 문제도 있고, 잦은 접근은 IP 차단을 부른다. 개인 용도 / 내부 테스트에 한정해서 쓰자. 상용 수집이라면 해당 서비스가 제공하는 API 를 쓰거나 계약을 맺는 게 맞다. 특히 robots.txt 와 utilization 규정은 최소한 읽어 보는 것.
CasperJS 는 PhantomJS 2.0 이 나오면서 WebKit 신버전을 쓸 수 있게 된 덕에 점점 실용성이 높아지고 있다. 그래도 슬슬 Selenium WebDriver + Chrome 쪽으로 옮겨갈 준비를 하는 게 좋을 듯.