05-01 10:05
Notice
Recent Posts
Recent Comments
관리 메뉴

Scientific Computing & Data Science

[Programming / WebApp] 네이버 영화 웹 스크랩핑(Web Scraping) 본문

Programming/Web App

[Programming / WebApp] 네이버 영화 웹 스크랩핑(Web Scraping)

cinema4dr12 2016. 9. 16. 19:46

이번 글에서는 네이버 영화 웹페이지의 현재 상영작의 타이틀 및 평점을 스크랩핑 하는 Web Application을 제작해 보도록 하겠다.

스크래핑하고자 하는 대상 웹 페이지는 네이버 영화:현재 상영영화이며,
주소는 
http://movie.naver.com/movie/running/current.nhn?order=reserve 이다.

영화 목록이 나열된 순서는 예매율이다.


개발환경

웹 스크래핑을 위한 Node Package는 cheeriorequest이다.
본 웹 어플리케이션 제작을 위한 개발환경은 다음과 같다:

  • Express : 4.13.4

  • Node.js : v6.5.0

  • MongoDB : v3.0.7

  • cheerio : v0.22.0

  • request : v2.74.0

버전이 반드시 일치할 필요는 없으며, 참고용임을 밝혀 둔다.

또한 혹시나(?) 하는 마음에 package.json 파일도 첨부한다.

{
  "name": "DataScraping",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "start": "nodemon app.js"
  },
  "dependencies": {
    "body-parser": "~1.15.1",
    "cheerio": "^0.22.0",
    "cookie-parser": "~1.4.3",
    "debug": "~2.2.0",
    "express": "~4.13.4",
    "express-session": "^1.14.1",
    "mongoose": "^4.6.0",
    "morgan": "~1.7.0",
    "multer": "latest",
    "pug": "^2.0.0-beta6",
    "request": "^2.74.0",
    "serve-favicon": "~2.3.0"
  }
}


Express Project 생성

본 어플리케이션은 Node-Express Framework을 기반으로 제작하므로, 우선 Express Generator를 통하여 어플리케이션 기본 템플릿을 생성하도록 한다.
이 과정에 대한 자세한 내용은 Express 템플릿 생성하기를 참고하기 바란다.
앞으로의 내용은 Express Project의 기본 골격이 준비되었다는 가정 하에 진행될 것이다.

Express Project 생성이 완료 되었으면, package.json에 정의된 Node Packages를 설치한다.

> sudo npm install


movie.js 라우터 작성

웹 스크래핑을 처리할 JavaScript 파일을 작성한다.
파일명을 "movie.js"로 하였으며, 경로는 {EXPRESS_PROJECT_ROOT}/routes/이다.

우선 전체 코드는 다음과 같다.

[{EXPRESS_PROJECT_ROOT}/routes/movie.js]


이제 코드를 부분 부분 따라가면서 설명하도록 하겠다.

var express = require('express');
var request = require('request');
var cheerio = require('cheerio');
var router = express.Router();

위의 코드는 필요한 Node Packages를 선언하는 부분이다.


var numOfMovies = 50;
var parsedResults = new Array();

numOfMovies는 데이터를 저장할 영화 목록의 총 개수를 정의한 것이며,
parsedResults는 저장할 메타데이터에 대한 배열이다.


router.get( '/', function( req, res ) {

  ...

} );

웹 브라우저의 주소창으로부터 '/movies' 요청이 들어올 때 실행되는 코드이다.
이 부분에 해당 페이지를 request하여 데이터를 불러오는 코드를 작성하도록 한다.


request('http://movie.naver.com/movie/running/current.nhn?order=reserve',
  function ( error, response, html ) {

    ...

} );

네이버 영화의 현재 상영작 페이지를 요청한 후, 이에 따른 callback 함수를 처리하는 부분이다.


if ( !error && response.statusCode == 200 ) {
  ...
}

페이지 요청에 에러가 없고, 응답에 이상이 없는 경우 데이터를 처리하도록 한다.


var $ = cheerio.load( html );
var cnt = 0;

cheerio가 응답된 html을 불러오도록 하고,
영화 목록을 50개만 불러올 수 있도록 카운터를 정의한다.


$('dt.tit').each( function ( i, element ) {
  ...
} );

이제부터가 핵심이 되는 코드이다.
웹 브라우저의 주소창에 "http://movie.naver.com/movie/running/current.nhn?order=reserve"를 입력하여 네이버 영화 현재 상영작 페이지로 이동하여 보자.
웹 브라우저의 개발자 도구를 열도록 한다.

HTML의 Elements를 <body> 태그로부터  쭈~욱  내려오면서 살펴보다 보면 "tit" class를 갖는 <dt> 태그를 발견할 수 있을 것이다.


이제 "tit" class를 갖는 모든 <dt> 태그에 대하여 데이터를 처리하도록 한다.


var movie_list = $(this);

"tit" class를 갖는 <dt> 태그 요소를 movie_list 변수에 저장한다.


var movie_title = movie_list.children().eq(1).text();

movie_list의 자식 오브젝트를 모두 얻어오고 (children()), 자식 오브젝트 중 두번째 오브젝트(.eq(1))의 문자열을 얻어온다 - JavaScript는 0-base index를 사용하기 때문에 index "1"이 두번째 오브젝트이다.
이 문자열이 영화 제목이다.


var star = movie_list.next();
var infoStar = star.children().eq(0);
var dd = infoStar.children().eq(1);
var star_t1 = dd.children().eq(0);
var a_href = star_t1.children().eq(0);
var num = a_href.children().eq(1);
위의 코드는 평점을 포함하는 태그를 찾는 과정이다.

즉, 아래 이미지의 태그를 찾는 것이다.


var movie_rating = num.text();

평점을 포함하는 태그의 문자열을 movie_rating 변수에 저장한다.


// Our parsed meta data object
var metadata = {
  movieTitle: movie_title,
  movieRating: movie_rating
};

// Push meta-data into parsedResults array
parsedResults.push( metadata );

영화의 제목과 평점을 변수 metadata에 JSON 포맷 형식으로 정의하고, parsedResults에 요소를 저장한다.


res.render( 'movie', {
  title: 'Movie Page Web Scraping',
  metadata: parsedResults
} );

웹 스크래핑을 통해 원하는 데이터를 모두 저장하였으면, 이 데이터를 실어서 "movie" 페이지로 전달하도록 한다.

위의 코드는 parsedResults를 metadata 변수로 전달하는 것이다.


movie.pug 페이지 작성

웹 스크래핑된 데이터(영화 제목 + 평점)를 표시할 페이지를 작성한다.
우선 전체 페이지 pug 코드는 다음과 같다.

html
    head
        title #{title}
        style.
          table {
              font-family: arial, sans-serif;
              border-collapse: collapse;
              width: 100%;
          }
          td, th {
              border: 1px solid #dddddd;
              text-align: left;
              padding: 8px;
          }
          tr:nth-child(even) {
              background-color: #dddddd;
          }
    body
      table
        tr
            th No.
            th Title
            th Rating
        each val, index in metadata
            tr
                td #{index + 1}
                td #{metadata[index].movieTitle}
                td #{metadata[index].movieRating}


이를 통해  렌더링된 웹 페이지는 다음과 같다.


each val, index in metadata
    tr
        td #{index + 1}
        td #{metadata[index].movieTitle}
        td #{metadata[index].movieRating}

"movie.js"로부터 전달받은 metadata의 모든 요소를 Table 형식으로 표시하는 과정이다.


웹 스크래핑 활용

간단한 웹 스크래핑 프로젝트를 진행해 보았다.
좀 더 진보된 활용을 하자면, 다른 포털으로부터도 데이터를 수집하여 통합 평점을 계산하여 본다든가, 일정시간 단위로 평점 데이터를 얻어와 실시간으로 평점의 변화를 시각화 하는 등의 프로젝트를 진행해 볼 수 있을 것이다.

영화 뿐만 아니라, 주가 변화 또는 금 시세, 원-환율 변화 데이터 등을 얻어와 자신만의 종합 자산 정보 페이지를 만들어 볼 수도 있을 것이다.


Comments