웹 크롤링 토이 프로젝트 (DB 저장부터 Metabase[BI Tool] 연결까지) – 2

웹 스크래핑 토이 프로젝트 -1 에 이어 다음 과정을 공유하고자 합니다. 지난 포스팅에서 백준 알고리즘 사이트에서 원하는 데이터를 출력하는 것까지 성공했습니다. 이번 포스팅에서는 가져온 데이터를 DB에 저장하고 저장한 데이터를 BI Tool로 시각화하는 것으로 마무리하겠습니다.

1. MongoDB 설치

웹 스크래핑 데이터를 DB에 저장하기 위해서는 DB Server가 필요합니다. 기존 계획에서 선정한 MongoDB 서버를 구축해보도록 하겠습니다.

brew tap mongodb/brew
brew install mongodb-community

MacOS 환경에서는 Homebrew를 통해 커맨드 한 줄로 MongoDB를 설치할 수 있습니다. (Homebrew 업데이트로 인해 기존 brew install mongodb는 더이상 동작하지 않습니다.) Windows 환경이신 분들은 다음 링크에서 MongoDB 를 설치하시면 됩니다.

brew services start mongodb-community  // MongoDB Server 실행
mongo                                  // DB Server 접속 (Window 사용자는 path 등록 필요)

위 명령어를 통해서 MongoDB 서버를 실행시킨 뒤 MongoDB 서버에 접속하면 아래와 같은 화면을 볼 수 있습니다. 아래 커서에 MongoDB 쿼리를 통해 DB 조작을 할 수도 있지만 결과들을 쉽게 확인할 수 있는 GUI Tool 도 같이 사용해 보도록 하겠습니다.

MongoDB Server 연결!

2. Robo 3T (MongoDB GUI Tool) 설치

커맨드에서 MongoDB 쿼리를 사용해도 되지만 MongoDB 쿼리가 익숙하지 않은 저같은 분들은 MongoDB GUI Tool 인 Robo 3T 를 설치하는 것을 추천합니다. 이 링크를 통해 Robo 3T 를 설치합니다.

Robo 3T 설치 완료!

설치가 완료 후 실행하면 위와 같은 화면을 볼 수 있습니다. 다음은 Robo3T Tool 과 Local MongoDB Server 를 연결해보도록 하겠습니다. create 버튼을 클릭 후 아래 그림처럼 Address 에 localhost : 27017 을 입력해주면 로컬 DB server 에 연결할 수 있습니다. (접속이 되지 않으신 분들은 Port 정보를 확인해보시거나 DB Server 상태를 확인하시면 됩니다.)

MongoDB Connection

3. MongoDB Database, Collection 생성

Robo 3T 를 통해 Database를 생성하겠습니다. GUI Tool 특성답게 간단하게 마우스 설정으로 Database를 만들 수가 있습니다. 아래 그림처럼 Crate Database를 클릭하시면 Database를 생성하실 수 있습니다. 저는 algoProj 라는 Database를 만들었습니다.

마우스로 Database 생성

다음은 Collection을 생성하겠습니다. Collection은 RDB에서 Table과 유사한 역할을 한다고 보시면 됩니다. Document (row) 들을 집합이라는 의미로 사용되고 있습니다. 이번 토이 프로젝트에서는 알고리즘 문제(Document)를 모두 저장할 Problem 라는 Collection를 만들도록하겠습니다. 이 또한 마우스로 쉽게 생성가능합니다.

마우스로 알고리즘 문제들을 저장할 Collection 생성

4. 웹 스크래핑 결과 DB 저장

DB Server 설치와 간단한 Database 구성도 모두 완료하였습니다. 이제 웹 스크래핑 코드 중에서 콘솔에 출력하는 부분을 DB에 저장하는 코드로 대체하면 됩니다.

python 코드로 DB 에 무언가를 저장해본적은 없지만 누군가가 만들어놓은 DB Driver 를 사용하면 쉽게 해결되는 문제라고 생각했습니다. 이럴때 필요한 것이 검색!! 구글링으로 awesome python 검색하여 찾은 Pymongo 라는 DB Driver Packasge를 사용해 보도록하겠습니다.

awesome-python 에서 MongoDB Driver 를 찾을 수 있다.

우선, pip 를 통해 pymongo 패키지를 설치합니다.

python -m pip install pymongo

다음은 MongoDB 연결을 위한 mongoDB.py 라는 파일을 생성 후 DB Connection 코드를 작성합니다. 세 줄의 코드로 MongoDB 서버에 algoProj Database 에 접근할 수 있습니다.

# mongoDB.py
# pymongo pacakge 의존성 추가
import pymongo

# DB Driver를 통한 Connection 생성 : 인자로는 DB Server 설정을 주입한다
connect = pymongo.MongoClient('localhost', port=27017)

# DB Server에서 algoProj Database 가져오기
db = connect.get_database('algoProj')

DB 연결에 성공하였다면 기존 코드의 콘솔 출력 부분을 DB에 저장하는 쿼리로 대체합니다.

from selenium import webdriver
from mongoDB import *

# Database에서 Collection 얻어오기
problem = db.Problem

backJoonCategoryUrl = "https://www.acmicpc.net/problem/tags";
# selenium webdriver
browser = webdriver.Chrome();
# 문제 분류 초기페이지
browser.get(backJoonCategoryUrl);

categorys = browser.find_elements_by_css_selector('table.table.table-bordered.table-striped tbody tr');

categoryNames = []
for category in categorys:
    categoryName = category.find_element_by_css_selector('td > a').text
    categoryNames.append(categoryName)

for categoryN in categoryNames:
    browser.get('https://www.acmicpc.net/problem/tag/' + categoryN)
    trs = browser.find_elements_by_css_selector('table#problemset tbody tr')
    for tr in trs:
        bj_num = tr.find_element_by_css_selector('td.list_problem_id').text
        title = tr.find_element_by_css_selector('td:nth-child(2)').text
        solvers = tr.find_element_by_css_selector('td:nth-child(4)').text
        submitCnt = tr.find_element_by_css_selector('td:nth-child(5)').text
        solveRate = tr.find_element_by_css_selector('td:nth-child(6)').text
        # 기존 콘솔 출력 부분을 주석 처리 후
        # print("{0} {1} {2} {3} {4}".format(bj_num, title, solvers, submitCnt, solveRate))
        
        # DB 저장 코드로 변경
        # replace_one에 upsert 속성을 주어 Document가 없는 경우 생성, 있는 경우 대체하도록 코드 작성 
        solveRate = float(solveRate.replace('%',''))
        problem.replace_one(
            {"bj_num": bj_num},
            {"bj_num": bj_num, "category": categoryN, "title": title, "solvers":solvers, "submitCnt": submitCnt, "solveRate": solveRate},
            upsert = True
        )

위의 코드를 실행시키면 Robo 3T 에서 Problem Collection에 알고리즘 문제 Document 들이 저장되어 있는 것을 확인할 수 있습니다.

알고리즘 문제 DB 저장 완료!!

5. Metabase (BI Tool)로 데이터 시각화하기

DB 저장된 데이터를 간편하게 시각화 할 수 있는 BI Tool, Metabase 를 설치하겠습니다. Metabase 사용해 본 적은 없지만 공식 홈페이지만 보더라도 디자인이 깔끔해서 좋습니다. 해당 링크에서 Metabase를 다운받아 설치합니다. Metabase Application를 실행합니다. 다음과 같은 화면이 나타나면 Let`s get started 버튼을 클릭해 진행하도록 합니다.

Metabase 실행시 시작화면

Metabase는 시작 전 크게 2가지 과정을 거치게 됩니다. 해당 3가지 과정은 Metabase Docs 친절하게 설명되어 있으니 참고하시면서 보시면 도움되리라 믿습니다. 2가지 과정은 다음과 같습니다.

5-1. Admin 계정 생성

Metabase는 웹 서버 형태로 제공됩니다. 초기 서버 Admin 계정을 생성할 필요가 있습니다. 간단한 사항들을 입력하고 Admin계정을 생성합니다.

Metabase admin 계정 생성

5-2. Connect DB Server

다음은 Metabase 에 사용될 DB 정보를 입력하는 것 입니다. 추후 사용하면서 다수의 DB 도 연결하여 사용할 수 있지만 설치해놓은 MongoDB Server와 연결하겠습니다. 아래처럼 입력한 뒤 다음 단계로 진행합니다.

Metabase DB Connection 생성

초기 설정을 성공적으로 마쳤다면 다음과 같은 초기 화면을 볼 수 있습니다. 역시 디자인이 깔끔하니 만족스럽습니다.

metabase 초기화면

초기 화면 아래 Our Data 항목에서 연결된 DB 를 확인할 수 있습니다. 연결된 DB 를 클릭 후 Problem Collection 을 열어보면 아래 처럼 쿼리를 시각화하여 보여줍니다.

간단한 쿼리의 경우에는 Metabase Editor를 사용하여 변경할 수 있으며 또한 쿼리 자체를 직접 만들어 조회해 볼 수도 있습니다. 그 외 Line, Scatter, Combo, Map 등 다양한 시각화(visualization)를 제공합니다. 상세하게 다루기에는 양이 많기에 본인이 버튼하나씩 눌러보면서 탐색하시거나 Metabase Docs를 참조하시면서 본인 입맛에 맞게 사용하시면 됩니다.

마침

포스팅을 완성하고 보니 코드 작성보다는 Tool 소개와 설치 작업이 80% 정도가 되는 것 같습니다. 필자는 위에서 소개한 것들을 상세하게 다루지는 못하였을 뿐더러 알지도 못합니다. 필요할 때마다 찾아가면서 작업하는 것이 집중도 잘되고 오래 기억이 남습니다. 원하는 기능만 간단하게 구현하니 빠르게 웹 스크래핑 토이 프로젝트가 뼈대를 갖추었습니다. 만족스럽니다. Metabase 디자인도 만족스럽니다.

프로젝트 뼈대에 추가할 만한 작업으로는 타 알고리즘 사이트 웹 스크래핑하여 DB에 저장하는 작업, python thread를 이용하여 웹 스크래핑 작업 시간을 줄이는 작업, Metabase 웹 서버를 도메인에 등록하고 클라우드 환경에 배포하여 다른 사용자들도 사용할 수 있게 하는 작업 등이 있습니다. 기회가 된다면 살을 붙이는 작업들도 포스팅 해보도록 하겠습니다.

답글 남기기

이메일 주소는 공개되지 않습니다.