[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초 간격으로 실행되도록 했다.