[nodejs] request, cheerio 를 이용한 웹페이지 크롤링

nodejs 를 이용하 웹페이지를 크롤링하는 것을 스터디 하고 있다. 아래는 nodejs의 request, cheerio 모듈을 이용하여 SIR 의 자유게시판의 제목, 작성자이름, ip 정보를 크롤링하는 코드이다. 자유게시판 리스트에 접속하여 게시글보기 링크의 href 값을 얻어 각 게시글보기 페이지에 접속하여 제목, 작성자명, ip 정보를 수집한다. SIR 사이트에 동시접속하는 것을 막기 위해 async, await 구문을 사용하여 순차적으로 게시글 보기가 실행되도록 했다.

사용모듈

const request = require('request').defaults({jar: true});
const cheerio = require('cheerio');

function downloadPage(url)
{
    return new Promise((resolve, reject) => {
        request(url, (error, response, body) => {
            if (error) reject(error);
            if (response.statusCode != 200) {
                reject('Invalid status code <' + response.statusCode + '>');
            }
            resolve(body);
        });
    });
}

function sleep(ms){
    return new Promise(resolve => {
        setTimeout(resolve, ms)
    });
}

async function getInfo(urls)
{
    try {
        for (i=0; i<urls.length; i++) {
            if (i > 0)
                await sleep(5000);

            var url = urls[i];
            var patt = /^https?:/;
            if (!patt.test(url))
                url = "https:" + url;
            var body = await downloadPage(url);

            var $ = cheerio.load(body);

            var title = $("#head_title", $("header.vbo_head")).text().trim();
            var name  = $("span.member", $("ul#head_info")).text().trim();
            var ip    = $("#info_name", $("ul#head_info")).children().remove().end().text().trim();

            console.log(title + " => " + name + " " + ip);
        }
    } catch (error) {
        console.log(error);
    }
}

try {
    request("https://sir.kr/cm_free", (error, response, body) => {
        var $ = cheerio.load(body);
        var hrefs = [];

        var lists = $("a.title_link", ".li_title", $("#sir_lbo"));

        lists.each(function() {
            var href = $(this).attr("href");

            hrefs.push(href);
        });

        if (hrefs.length > 0) {
            getInfo(hrefs);
        }
    });
} catch (error) {
    console.log(error);
}

각 게시글보기 실행은 await sleep(5000);  코드를 통해 5초 간격으로 실행되도록 했다.

편리

PHP와 MariaDB, jQuery 등을 사용해 게시판, 쇼핑몰 솔루션을 개발합니다. 그누보드5와 영카트5 개발에 참여 했습니다. Linux와 Nginx는 물론 WordPress, Git 등에도 관심이 많습니다. 자전거 타기 및 사진 촬영을 취미로 하고 있습니다.

카카오톡 플러스친구 채팅 : NCUBE.NET

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.