본문 바로가기

이것저것

노드로 게시판 파싱해보기1

지금까지 배운걸로 프로젝트를 작게 진행해보고 싶어서 전에 있던 연구실 게시판을 파싱 해보기로 하였다. 이번 프로젝트에서 내가 사용하려는 모듈은 express, http, request 총 3가지다. 내가 파싱하려는 대상은 글의 목록이다.

 

 

파싱을 하기 위해서 내가 파싱하려는 연구실 게시판을 먼저 확인하였다. 전에 있던 연구실 게시판은 이렇게 생겼다.

rclab게시판 구성

 

 

사이트 전체에서 내가 필요한 부분은 강의 게시판 부분에서 표 안에 내용이다. 이 부분의 마크업을 확인하기 위하여 f12를 눌러서 개발자 모드로 들어갔다. 다음과 같이 코드가 구성되어 있었다.

게시판을 나타내는 마크업

 

 

 

여기서 글 목록을 선택하여 다시 tr태그에서 어떻게 각각의 목록이 존재하는지 확인하였다. 글 목록은 다음과 같이 구성되어 있었다.

글 목록에 대한 마크업 구성

 

 

이렇게 마크업을 확인하고 게시판을 파싱하기 위해 세운 방법은 다음과 같다. 최대한 지금까지 공부한 내용을 사용하려고 하였다.

1. express객체로 서버를 만든다.

2. 서버가 만들어지면 미들웨어를 이용하여 파싱하는 부분으로 넘어간다.

3. 미들웨어 함수안에 request()함수를 넣어둔다.

4. request()함수의 매개변수로 콜백함수를 넣어서 게시판을 마크업으로 읽어온 후 필요한 부분을 파싱한다.

5. 파싱이 종료되면 write()함수로 클라이언트에 넘겨준다.

 

 

 

우선 모듈을 세 가지를 불러왔다.

const express = require('express')
const http = require('http')
const request = require('request')

 

 

그 후 express객체를 만들고 3000번 포트를 이용하여 서버를 생성하였다.

const app = express();

app.set('port', process.env.PORT || 3000);

http.createServer(app).listen(app.get('port'), () => {
    console.log(`${app.get('port')}에서 실행중`)
});

 

 

그리고 미들웨어를 이용하여 게시판 파싱하는 부분을 만들었다. 미들웨어는 use()함수로 구현하였다. 미들웨어 함수로는 request()함수를 사용하였다. request()함수는 원하는 곳에 마크업을 읽어오는 역할을 한다. request()함수는 콜백함수를 함수 인자로 사용하였고 콜백함수 부분에서 파싱을 담당한다. 

app.use((req, res, next) => {
    request('http://rclab.kmou.ac.kr/bbs/board.php?bo_table=2019_2_NA', (err, response, body) => {
        const wherestart = body.indexOf('<!-- 게시판 카테고리 시작 { -->');
        const whereend = body.indexOf('<!-- 게시판 검색 시작 { -->');
        body = body.substring(wherestart, whereend);
        
        const wheretablestart = body.indexOf('<table>')
        const wheretableend = body.indexOf('</table>')
        body = body.substring(wheretablestart, wheretableend);

        let check = false;
        const arr = body.split('\r\n')

        arr.reverse()

        let result = arr.reduce((accumulator, current) => {
            if(current.indexOf(`</a>`) != -1) {
                check = true;    
            }
            else if(check) {
                check = false;
                current = current.trim()
                accumulator.push(current)
            }
            return accumulator
        }, []);
        
        result.pop();
        result = result.join('<br>');
        result = '<p>' + result + '</p>';

        res.writeHead(200, {'Content-Type' : 'text/html; charset=utf-8'});
        res.write(result);
        res.end();
    })
});

파싱하는 부분을 좀 더 자세히 설명하자면 우선 게시판 시작 부분과 끝 부분을 설정하여서 필요 없는 부분은 날렸다. 그 후 다시 table 태그 안에 부분만 얻어 내고 다른 필요 없는 부분을 한 번더 날렸다. 그리고 각 코드의 줄을 구분하기 위해 필요한 부분을 '\r\n'으로 나누어 배열 안에 저장하였다. 그리고 reduce함수를 사용하여 <a>태그로 시작한 다음 부분은 반드시 글의 목록이기 때문에 그 부분만 배열의 결과로 담았다. 결과로 담은 배열은 다시 <br>태그를 이용하여 문자열로 합치고 마지막에 <p>태그를 붙였다. 그런 후 클라이언트에 다시 전송해주는 과정을 거쳤다. 

 

 

결과는 다음과 같다.

파싱 결과

 

 

토이 프로젝트를 위해 배운것을 적용해 본 좋은 프로젝트였다. 다음에는 좀 더 업그레이드 된 프로젝트로 돌아와야겠다.

https://github.com/hansanguk0222/rclabParsing