20141024

CasperJS로 간단한 스크래핑 파이프라인

특정 사이트에서 주기적으로 데이터 긁어와야 하는 업무가 생김. 그 사이트가 js 렌더링이라 curl로는 안됨. phantomjs 기반 CasperJS로 붙여봄.

var casper = require('casper').create({
    verbose: false,
    pageSettings: {
        userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36'
    }
});

var results = [];

casper.start('https://example.com/list', function() {
    this.waitForSelector('.item-row');
});

casper.then(function() {
    results = this.evaluate(function() {
        var rows = document.querySelectorAll('.item-row');
        return Array.prototype.map.call(rows, function(r) {
            return {
                title: r.querySelector('.title').innerText,
                price: r.querySelector('.price').innerText
            };
        });
    });
});

casper.run(function() {
    require('fs').write('out.json', JSON.stringify(results), 'w');
    this.exit();
});

파이프라인:

cron → casperjs script.js → out.json → node에서 읽어서 postgres에 insert. 단순.

문제들:

1. 메모리 누수. 오래 돌리면 phantomjs 프로세스가 1GB씩 먹음. 일회성으로 exit 하는게 속편함.
2. 사이트가 CAPTCHA 걸면 끝. 실제로 몇 달 후 차단당함ㅠ
3. HTTPS 인증서 에러 (TLS) 뜰 때가 있음. --ignore-ssl-errors=yes 옵션으로 우회.

이 사이트는 robots.txt도 딱히 막혀있진 않지만 업무 관련이라 느리게 돌림. 요청 사이 casper.wait(3000, ...) 딜레이 줌. 매너는 기본.

요즘 나오는 nightmare.js도 슬쩍 보는중. electron 기반이라 phantom 불안정 이슈는 좀 나을듯.