NodeJS 로 okky.kr 의 메인 홈페이지를 크롤링하는 법을 알아볼까 합니다.
처음이니 만큼 이미지나 로그인은 다음에 하겠습니다.
이 글에서는 원하는 웹 사이트의 원하는 부분의 텍스트를 가지고 오는 방법에 대해 알아보겠습니다.
개발 환경은 Node v12.16.1 / IntelliJ IDEA 로 하였습니다.
그리고 axios / cheerio 를 사용하였습니다.
var axios = require("axios");
var cheerio = require("cheerio");
var log = console.log;
var url = ("https://okky.kr");
설치는 터미널 창에서 npm install [라이브러리명] 으로 입력해주시면 설치 됩니다.
에러가 날 경우 구글링 해주시거나 권한 문제 일 수 있으니 sudo를 앞에 붙여 보시기 바랍니다.
const getHtml = async () => {
try {
return await axios.get(url);
} catch (error) {
console.error(error);
}
};
axios는 해당 url에서 html 파일을 받아줍니다.
정상적인 url이라면 200을 받고 데이터를 받습니다.
url이 존재하지 않는다면 404를 받고 console로 에러를 표시합니다.
getHtml().then(html => {
let liList = [];
var $ = cheerio.load(html.data);
var $bodyList = $("div.col-sm-8.main-block-left div.list-title-wrapper");
$bodyList.each(function(i, elem) {
if(i < 10) {
liList[i] = {
title: $(this).find('h5 > a').text(),
url: url + ($(this).find('h5 > a').attr('href')),
writer: $(this).find('a.nickname').text(),
date: $(this).find('span.timeago').text()
};
};
});
var data = liList.filter(n => n.title);
return data;
}).then(res => log(res));
url에서 받은 html 파일을 cheerio를 이용하여 필요한 부분만 추출해야 합니다.
이 글에서 최종 목표는 홈페이지에 노출된 Q&A 글 10개의 제목, url, 작성자, 작성시간을 가지고 오는 것입니다.
#index > div.col-sm-8.main-block-left > div:nth-child(1)
위의 경로가 Q&A 블록의 위치 입니다.
10개의 Q&A 글 전체 중에서 각각 한줄씩 배열로 저장하여야 합니다.
Q&A 한 줄의 경로는 다음과 같습니다.
#index > div.col-sm-8.main-block-left > div:nth-child(1) > div > ul > li:nth-child(1)
그 경로 내에서 제목, url 부분과 작성자, 작성시간 부분으로 나누어 집니다.
제목, url 부분의 경로는
#index > div.col-sm-8.main-block-left > div:nth-child(1) > div > ul > li:nth-child(1) > div > h5 > a
위 a 태그의 text에는 제목이 저장되어 있고, href 속성에는 url이 저장되어 있습니다.
작성자, 작성시간 부분의 경로는
#index > div.col-sm-8.main-block-left > div:nth-child(1) > div > ul > li:nth-child(1) > div > h5 > div > div > div
내부의 a 태그의 text 내용은 nickname(작성자)이고 span 태그의 text는 작성했던 시간의 정보가 담겨있습니다.
위의 빨간색으로 표시한 div가 위 코드에서 $bodList 의 뒤에 div.list-title-wrapper 입니다.
var $bodyList = $("div.col-sm-8.main-block-left div.list-title-wrapper");
bodyList에 저장하는데 axios에서 받아온 html 에서 col-sm-8.main-block-left라는 클래스명을 가진 div를 찾으라는 의미 입니다.
여기서 공백 한칸을 두고 div.list-title-wrapper를 넣은 것은 위의 div의 자손 중에서 list-title-wrapper라는 클래스명을 가진 div 태그를 저장하겠다는 의미 입니다.
여기서 자손이란 div 태그 아래에 해당하는 모든 태그를 말하며 비슷한 말로는 자식이 있습니다.
자식은 자신의 바로 아래에 해당하는 태그를 말하며 코드로 작성시 공백 대신 > 라는 기호를 넣어 표시합니다.
( 자세한 내용은 'CSS 자식 자손'을 검색해보시면 됩니다.)
이렇게 해서 위의 모든 코드를 합하면 okky.kr에서 메인에 노출되어 있는 10개의 Q&A 글의 데이터만 크롤링 해옵니다.
var axios = require("axios");
var cheerio = require("cheerio");
var fs = require('fs');
var log = console.log;
var url = ("https://okky.kr");
var getHtml = async () => {
try {
return await axios.get(url);
} catch (error) {
console.error(error);
}
};
getHtml().then(html => {
let liList = [];
var $ = cheerio.load(html.data);
var $bodyList = $("div.col-sm-8.main-block-left div.list-title-wrapper");
$bodyList.each(function(i, elem) {
if(i < 10) {
liList[i] = {
title: $(this).find('h5 > a').text(),
url: url + ($(this).find('h5 > a').attr('href')),
writer: $(this).find('a.nickname').text(),
date: $(this).find('span.timeago').text()
};
};
});
var data = liList.filter(n => n.title);
return data;
}).then(res => log(res));
결과 값.
[
{
title: 'static과 singleton 사용에 대한 질문',
url: 'https://okky.kr/article/684672',
writer: '공부해야해',
date: '2020-02-28 10:55:43'
},
{
title: 'node.js 및 java script canvas에 대해 질문드립니다.',
url: 'https://okky.kr/article/684671',
writer: '오징옆',
date: '2020-02-28 10:55:08'
},
{
title: 'SQL WHERE 절에서 일부분만 부정 조건을 줄 수 있을까요?',
url: 'https://okky.kr/article/684670',
writer: '정신못차리는중',
date: '2020-02-28 10:49:36'
},
{
title: '안녕하세요 신입 퍼블리셔 입니다. 스와이프 슬라이드 플러그인 질문있습니다.',
url: 'https://okky.kr/article/684667',
writer: '쫑쫑쫑',
date: '2020-02-28 10:43:04'
},
{
title: '코어라이브러리는 뭘 뜻하는걸까요?',
url: 'https://okky.kr/article/684665',
writer: '칼잇우마',
date: '2020-02-28 10:34:51'
},
{
title: 'css템플릿사용중 position문제..',
url: 'https://okky.kr/article/684660',
writer: '루루루룰룰룰',
date: '2020-02-28 10:23:05'
},
{
title: 'imagecreatefrompng 이미지 출력관련..',
url: 'https://okky.kr/article/684659',
writer: '냉국이',
date: '2020-02-28 10:22:40'
},
{
title: '자바주소클릭을 어떻게 하나요.',
url: 'https://okky.kr/article/684658',
writer: 'noela',
date: '2020-02-28 10:22:30'
},
{
title: '테이블명 관련 질문.',
url: 'https://okky.kr/article/684653',
writer: '개발하는사람1',
date: '2020-02-28 10:10:45'
},
{
title: 'mysql 쿼리 관련 질문',
url: 'https://okky.kr/article/684638',
writer: 'ro개린이',
date: '2020-02-28 09:24:34'
}
]
다음 포스팅에서는 크롤링한 데이터를 메모장에 저장하는 방법과 로그인하여 크롤링 하는 방법에 대해 올리겠습니다.
'Program language > NodeJS' 카테고리의 다른 글
| [puppeteer] 강력한 $$eval 사용법. (0) | 2020.03.30 |
|---|---|
| [nodeJS] 브라우저로 서버 일 시키기. (0) | 2020.03.27 |
| 웹에서 버튼을 누르면 크롤링이 되도록 하기. (0) | 2020.03.05 |
| pupeteer 활용한 네이버 메일 크롤링 하기. (0) | 2020.03.04 |
| NodeJS 로 크롤링한 데이터 .txt 저장 (0) | 2020.02.28 |