본문 바로가기
Runtime/Node.js

29. 크롤링

by 김엉배 2023. 4. 30.
728x90
반응형

 

1. 크롤링이란

 

 

  • 웹 페이지를 그대로 가져와서 웹 페이지 안에 있는 필요한 데이터를 추출해 내는 것을 말한다.

 

 

2.  axios · cheerio 모듈

 

 

  • axios는 브라우저, Node.js를 위한 Promise API를 활용하는 HTTP 비동기 통신 라이브러리다. 웹 페이지를 가져오는 사용.
npm install axios

 

  • cheerio는 브라우저에서 사용하는 jquery 같이, Node.js에서 axios를 통해 가져온 웹 페이지를 파싱 하여 전체 페이지 중에서 
    필요한 부분의 정보만 가져올 수 있게 해준다.
npm install cheerio

 

 

 

3.  인프런 강의 목록 크롤링

 

 

→ IT 온라인 강의 플랫폼인 '인프런'에서 제공하는 프로그래밍 강의 목록을 크롤링

  • 인프런 사이트(https://www.inflearn.com/)에 접속해서 강의 목록을 보여주는 웹 페이지 URL을 확인
  • 인프런 상단 메뉴에서  '강의' 메뉴를 클릭하면 URL 주소가 "https://www.inflearn.com/courses"로 바뀌는 것을 확인
    '자바스크립트'라는 키워드로 검색하면 URL 주소가 "https://www.inflearn.com/courses?order=seq&skill=javascript" 변경

인프런 강의 목록

  • getHTML 함수 작성(검색 키워드를 파라미터로 전달받고, 인프런에서 주어진 검색 키워드를 통해 검색 키워드를 통해 검색되는 강의                                   목록에 해당하는 페이지를 가져오는 기능을 구현)
const axios = require("axios");
const cheerio = require("cheerio");

// 검색 키워드를 사용해서 인프런에서 강의 목록 웹 페이지 가져오는 함수
const getHTML = async (keyword) => {
  try {
    return await axios.get(
      "https://www.inflearn.com/courses?s=" + encodeURI(keyword)
    );
  } catch (err) {
    console.log(err);
  }
};

 

  • 가져온 페이지를 파싱한 후 필요한 강의 정보만 추출하는 함수 작성
// 가져온 웹 페이지를 파싱해서 필요한 정보(강의 정보)만 추출하는 함수
const parsing = async (page) => {
  const $ = cheerio.load(page); // 웹 페이지를 파싱이 가능한 구조로 로드 시킴

  // 강의 목록 웹 페이지 html 구조에서 클래스명이 .course_card_item 인 html 요소에 강의 정보가 있기 때문에 이 부분에 해당하는 html 요소만 가져옴.
  const $courseList = $(".course_card_item"); 

  let courses = []; // 강의 정보를 담을 배열
  $courseList.each((idx, node) => { // 가져온 강의 목록 수 만큼 반복문 수행
    const title = $(node).find(".course_title:eq(0)").text(); // 강의 제목
    const instructor = $(node).find(".instructor").text(); // 강의 제공자

    // 수강료는 할인중인 경우는 '₩수강료₩할인된수강료' 형식 사용
    // 수강료가 무료인 경우는 '무료'
    // 수강료가 할인중이지 않을 때는 '₩수강료' 형식 사용
    const prices = $(node).find(".price").text().split("₩"); // 수강료 전체(수강료, 할인된 수강료)
    const rating = $(node).find(".star_solid").css("width"); // 별점
    const imgSrc = $(node).find(".card-image > figure > img").attr("src"); // 강의 썸네일 이미지

    const originalPrice = (prices[0] == "무료")?"무료":prices[1]; // 수강료
    const discountPrice = (prices.length == 3)?prices[2]:originalPrice; // 할인된 수강료

    courses.push({
      title: title, // 강의 제목
      instructor: instructor, // 강의 제공자
      originalPrice: originalPrice, // 수강료
      discountPrice: discountPrice, // 할인된 수강료
      rating: rating, // 별점
      imgSrc: imgSrc, // 강의 썸네일 이미지
    });
  });

  return courses;
};

 

  • getHTML(), parsing() 두 개의 함수를 사용해 인프런에서 원하는 강의 목록을 가져오는 전체 코드
const axios = require("axios");
const cheerio = require("cheerio");

// 검색 키워드를 사용해서 인프런에서 강의 목록 웹 페이지 가져오는 함수
const getHTML = async (keyword) => {
  try {
    return await axios.get(
      "https://www.inflearn.com/courses?s=" + encodeURI(keyword)
    );
  } catch (err) {
    console.log(err);
  }
};

// 가져온 웹 페이지를 파싱해서 필요한 정보(강의 정보)만 추출하는 함수
const parsing = async (page) => {
  const $ = cheerio.load(page); // 웹 페이지를 파싱이 가능한 구조로 로드 시킴

  // 강의 목록 웹 페이지 html 구조에서 클래스명이 .course_card_item 인 html 요소에 강의 정보가 있기 때문에 이 부분에 해당하는 html 요소만 가져옴.
  const $courseList = $(".course_card_item"); 

  let courses = []; // 강의 정보를 담을 배열
  $courseList.each((idx, node) => { // 가져온 강의 목록 수 만큼 반복문 수행
    const title = $(node).find(".course_title:eq(0)").text(); // 강의 제목
    const instructor = $(node).find(".instructor").text(); // 강의 제공자

    // 수강료는 할인중인 경우는 '₩수강료₩할인된수강료' 형식 사용
    // 수강료가 무료인 경우는 '무료'
    // 수강료가 할인중이지 않을 때는 '₩수강료' 형식 사용
    const prices = $(node).find(".price").text().split("₩"); // 수강료 전체(수강료, 할인된 수강료)
    const rating = $(node).find(".star_solid").css("width"); // 별점
    const imgSrc = $(node).find(".card-image > figure > img").attr("src"); // 강의 썸네일 이미지

    const originalPrice = (prices[0] == "무료")?"무료":prices[1]; // 수강료
    const discountPrice = (prices.length == 3)?prices[2]:originalPrice; // 할인된 수강료

    courses.push({
      title: title, // 강의 제목
      instructor: instructor, // 강의 제공자
      originalPrice: originalPrice, // 수강료
      discountPrice: discountPrice, // 할인된 수강료
      rating: rating, // 별점
      imgSrc: imgSrc, // 강의 썸네일 이미지
    });
  });

  return courses;
};

// 인프런에서 제공하고 있는 강의중 파라미터로 전달한 키워드를 통해 검색된 강의 목록 가져오는 함수
const getCourse = async (keyword) => {
  const html = await getHTML(keyword);  // 인프런 강의 목록 페이지 가져오기
  const courses = await parsing(html.data); // 페이지를 파싱한 후 강의 정보를 담은 배열 가져오기
  console.log(courses);
};

getCourse("자바스크립트"); // 인프런 강의 목록 가져오기

 

  • Node.js로 실행하게 되면 강의 정보를 다음 배열로 가져오게 된다.

728x90
반응형

'Runtime > Node.js' 카테고리의 다른 글

30. forever  (2) 2023.05.01
28. 웹소켓  (1) 2023.04.30
27. 엑셀 파일 처리(엑셀 파일 생성)  (4) 2023.04.26
26. 엑셀 파일 처리(엑셀 파일 내용 수정)  (3) 2023.04.24
25. 엑셀 파일 처리(엑셀 파일 읽기)  (4) 2023.04.24