엘리스 AI트랙 4기/프로젝트

express 웹서비스 프로젝트에 뉴스 크롤링 추가하기_1탄

남쪽마을밤송이 2022. 5. 11. 20:51

 [01 크롤링이란? ] 

  • 크롤링(crawling) 혹은 스크레이핑(scraping)은 웹 페이지를 그대로 가져와서 거기서 데이터를 추출해 내는 행위이다.
  • 크롤링하는 소프트웨어는 크롤러(crawler)라고 부른다.
  • 검색 엔진에서도 유사한 것을 필수적으로 사용하는데,  상의 다양한 정보를 자동으로 검색하고 색인하기 위해 사용한다. 네이버, 구글 등도 이런 봇을 이용해 운영된다.
  • Python이 이 분야의 선두주자로서, 대표적인 파이썬 라이브러리의 예로 beautifulsoup가 있고 그 외에도 selenium이라는 라이브러리가 인기를 끌고있다.
  • 하지만 나는 nodejs를 사용한 프로젝트를 진행중이기 때문에 Javascript의 라이브러리를 이용해서 기능을 구현했다.

출처: https://namu.wiki/w/%ED%81%AC%EB%A1%A4%EB%A7%81

 

 [02 크롤링 준비 ] 

 (1) 크롤링은 불법일까? 

  • 결론적으로 말하면 '크롤링'하는 '행위' 자체는 불법이 아니다.
  • 생각해보면 공개된 웹사이트를 사람이 직접 탐색하는 것이나, 프로그램인 크롤링 봇이 웹사이트를 탐색하는 것은 사이트를 방문하고, 서버에 정보를 요청한다는 점에서 동일하기 때문이다.
  • 크롤링으로 소송이 난 사례들을 보면 요점은 크롤링을 하는 행위보다는 크롤링한 데이터를 가지고 추가적인 작업을 한 것에 대한 판결이다.
  • 따라서 누군가에게 금전적인 손실을 입게 만들거나, 상대방에서 데이터 사용에 대한 동의 없이 임의로 데이터를 가공한 것으로 금전적인 이익을 보면 위법하다고 보게 되는 것이기 때문에, 개인이 공부나 실습을 목적으로 하는 것은 큰 문제가 없다고 봐도 될 것 같다.

출처: https://redfox.tistory.com/31

 (2) robots.txt 파일이란? 

  • 위에서 크롤링 행위 자체는 불법이 아니라고 했지만, 그럼에도 불구하고 무분별한 크롤링 행위를 막고 크롤링 봇들의 행동을 제한하기 위한 규약이 robots.txt 파일이다.
  • 권고안이라서 꼭 지킬 의무는 없지만 서버의 트래픽이 한정돼있거나 검색엔진에의 노출을 원하지 않는 경우 이 robots.txt에 "안내문" 형식으로 특정 경로에 대한 크롤링을 자체해주라고 권고하는 것이다.
  • 의무는 아니지만 지키는 것이 매너이며 지키지 않는다면 서버 주인이 규칙을 지키지 않는 크롤링을 확인하고 크롤러의 IP를 차단할수도 있다.
  • 이러한 robots.txt 파일은 도메인의 최상위(root) 경로에 존재하기 때문에 사이트 도메인 뒤에 /robots.txt를 붙이면 확인할 수 있을 것이다.
    • 나의 경우 게임 추천 웹 서비스 프로젝트를 진행하던 중이었기 때문에 메인페이지에 게임 뉴스를 넣고 싶다는 의견이 나왔고 따라서 뉴스 사이트 크롤링을 시도하게 되었다.
    • 따라서 아래부터는 게임 메카(https://www.gamemeca.com)라는 사이트의 크롤링 실습 내용이다.

 (4) robots.txt 파일 확인 

  • 게임 메카 사이트의 robots.txt 파일을 보면 다음과 같았다.
    • 단순한 편인 것 같은데 대충 해석해보면 Mediapartners-Google agent에 대해는 제한하는 것이 없고 다른 모든 agent에 대해서는 /data_move/ 아래 경로 전체와 /manager/ 아래 경로 전체 등을 제한한다는 뜻이다.

출처: https://namu.wiki/w/robots.txt

 (5) 요청 경로 확인 

  • robots.txt 파일도 확인했으니 사이트를 탐색하면서 내가 요청을 보내서 크롤링 할 페이지를 결정하자.
  • 사이트를 대충 보니 온라인 / PC / 비디오 / 웹게임 / 모바일 카테고리에 따라 뉴스를 확인할 수 있었다.

  • 그리고 위 경로에서 각 카테고리 별로 ca라는 query parameter만 바뀌는 구조였다.
  • 따라서 나는 프론트의 요청에 따라 다섯 가지 카테고리로 분류하여 아래와 같은 경로로 요청을 하기로 했다.
https://www.gamemeca.com/news.php?ca=${category}

 

 [03 데이터 추출 ] 

 (1) 필요한 라이브러리 설치하기 

  • 요청을 보낼 경로까지 결정했으면 이제 실제로 요청을 보내 응답 data를 가공하면서 원하는 데이터만을 추출해야 한다.
  • nodejs express 환경에서 웹크롤링을 하기 위해서는 여러가지 방법이 있겠지만 나는 request 라이브러리와 cheerio 라이브러리를 사용했다. request 라이브러리는 아직 많이 쓰이지만 deprecated(개발중지)된 라이브러리라서 대신 axios를 사용해도 좋을 것 같다.
    • 개발환경(vscode)에서  npm i request npm i cheerio  로 각각 설치해준다.
  • 그리고 크롤링을 사용할 부분에 import한 뒤 편한대로 클래스나 함수를 다음과 같이 생성해준다.
const OutsideApi = {
  // 온라인: "O" | PC: "P" | 비디오: "V" | 웹게임: "W" | 모바일: "M"
  getNews: async (category) => {
    return new Promise((res, rej) => {
      request(
      // 요청 경로 url와 요청 method 종류
        {
          url: `https://www.gamemeca.com/news.php?ca=${category}`,
          method: "GET",
        },
	// 콜백 함수
        (error, response, body) => {
          if (error) {
            console.error(error);
            rej(new Error("error"));
          }
          if (response.statusCode === 200) {
            // cheerio를 활용하여 body에서 데이터 추출
            const $ = cheerio.load(body);
            console.log($);
	    // result에 1. 뉴스글 url / 2. 뉴스 썸네일 / 3. 뉴스제목
            const result = [];
            res(result);
          }
        }
      );
    });
  }
}
  • 여기까지만 작성하고 변수 $에 뭐가 들어있는지 확인해보기 위해 라우터쪽 코드를 작성하고 postman으로 요청해보면 다음과 같이 알 수 없는 형태의 응답이 출력된다.
  • 다음 포스팅에서는 아래 응답에서 실제로 내가 필요한 데이터를 추출하는 방법을 다뤄보겠다.