본문 바로가기
JavaScript

Node.js에서 스크래핑을 해보자

by Vintz 2021. 10. 29.
반응형

웹 스크래핑(크롤링) 하기

원본 URL의 콘텐츠를 스크래핑(크롤링)해서 상세 페이지를 구현할 일이 생겼다. 구글링과 여러 삽질 끝에 결국 성공했다. 직접 코드를 작성 해보면서 테스트 하는 것도 빠르고 좋은 방법인 것 같다.

 

시작 하기전 원본 URL의 HTML을 가져올 때 사용하는 라이브러리와 그 결과로 원하는 콘텐츠를 뽑아서 사용할 라이브러리 설치가 필요하다. 나같은 경우 브라우저와 Node.js 환경에서 둘 다 사용이 가능한 axios와 비교적 예제도 많고 문법이 익숙한 cheerio를 선택했다.

axios 외엔 request
cheerio 외엔 puppeteer, playwright 등이 있다.

설치하기

npm i cheerio axios

가져올 콘텐츠 정하기

예시로 CSR과 SSR 이해하기 글의 콘텐츠를 가져와 보자. 개발자 도구를 사용하면 원하는 콘텐츠의 셀렉터를 쉽게 가져올 수 있다.

개발자 도구의 요소 검사하기 클릭
이렇게 하면 쉽게 셀렉터를 가져올 수 있다.

텍스트 가져오기

const axios = require('axios');
const cheerio = require('cheerio');
const log = console.log;

const getHtml = async () => {
  try {
    return await axios.get('https://onlydev.tistory.com/102');
  } catch (error) {
    console.error(error);
  }
};

getHtml()
  .then((html) => {
    // axios 응답 스키마 `data`는 서버가 제공한 응답(데이터)을 받는다.
    // load()는 인자로 html 문자열을 받아 cheerio 객체 반환
    const $ = cheerio.load(html.data);
    const data = {
      mainContents: $('div.entry-content > div > p:nth-child(25)').text(),
    };
    return data;
  })
  .then((res) => log(res));

위 코드에서 getHtml 함수를 통해 비동기로 html 파일을 가져온다. 그 후 반환되는 Promise 객체의 결과값을 cheerio를 이용하여 원하는 콘텐츠를 뽑아낸다.

결과값

HTML 가져오기

getHtml()
  .then((html) => {
    const $ = cheerio.load(html.data);
    const data = {
      mainContents: $('#content > div.inner > div.post-cover')
        .html()
        // 불필요한 \n과 \t 제거
        .replace(/[\n\t]/g, ''),
    };
    return data;
  })
  .then((res) => log(res));

cheerio의 html 함수는 셀렉터의 자식 요소들을 반환한다.

결과값

태그의 속성 가져오기

getHtml()
  .then((html) => {
    const $ = cheerio.load(html.data);
    const data = {
      url: $('div.entry-content > div > p:nth-child(78) > a').attr('href'),
    };
    return data;
  })
  .then((res) => log(res));

결과값

그 외 함수들

  • children(): 인자로 셀렉터를 문자열로 받아 cheerio 객체에서 선택된 요소에서 해당하는 모든 태그들을 반환한다. (ul의 li들 등)
  • each(): 인자로 콜백 함수를 받아 태그들의 배열을 순회 하면서 실행한다.
  • find(): 인자로 셀렉터를 문자열로 받아 해당하는 태그를 반환한다.
  • addClass(): 인자로 문자열을 받아 cheerio 객체에서 선택된 요소에 클래스를 추가한다.
  • val(): cheerio 객체에서 선택된 요소의 값을 가져온다. (input, select, textarea 등)

참고

Node.js 에서 웹 크롤링하기 - yesdoing.log
Cheerio 사용해서 HTML파싱하여 Scraping하기 - lightcode
Cheerio
반응형