본문 바로가기

일상+자잘한 일/개발일지-unsolved.hgu

[Unsolved.ac/백엔드-2] 2번째 개발일지

개발 내용 3줄 요약

1. APIs 호출 방법 정리

2. Croller 공부 및 DB 연동

3. RabbitMQ 공부 및 테스트

 

개발 소감

OS에서 배운 지식이 백엔드 개발에서 필요하게 될 줄은 몰랐다. 프로세스간 통신을 위해서 message queue를 사용하게 되었는데, cs 지식이 도움이 됨을 느끼는 나날이다.

 

우선 rabbitMQ와 selenium을 처음 써봤는데 생각보다 다루기 쉽게 잘 만들어져있어서 좋았다.

ISSUE

  • Beautifulsoup의 동적 사이트 크롤링 불가
  • 문제 정보 크롤링시 오류 발생
    (문제 난이도가 없는 경우, 페이지가 없는 경우)

배운 내용

  • RabbitMQ 사용 방법 및 message queue 비교
  • BS, Selenium과 같은 크롤러 사용법

APIs 호출 방법 정리


APIs 사용과 관련해서 문제점이 많았는데 고민하던 부분을 말끔하게 해결할 방법을 구상했다.

 

문제점은 다음과 같았다.

    1. APIs는 약 15분 250회 정도이며 한 번에 50개의 아이템만 가져올 수 있다.

    2. 유저가 새롭게 풀어낸 문제를 알 수 없어 유저가 풀어낸 문제 목록을 모두 가져와야한다.

 

Real-time으로 streaming은 불가능에 가깝고 최대한 실시간으로 보여주는 방법을 고민했다.

    1. 각 유저별로 갱신되는 시각을 지정

        예시: 1번~3번 유저는 새벽2시, 4~10번 유저는 새벽2시 16분....

        단점: 24시간 간격 발생, 갱신이 필요하지 않은 유저도 갱신 - 치명적 API 횟수 낭비

 

    2. 갱신해야할 유저 목록을 받아와 유저들만 api 횟수에 맞추어 갱신

        예시: 우리학교 학생 목록을 모두 호출하여 푼 문제수가 달라진 학생들만 선택해 횟수에 맞춰 갱신

        단점: 호출 횟수 초과 순간 감지 후 유저 목록 저장 방법 부재, 다음 api턴에 실패 지점부터 이어나갈 방법 부재

 

그러던 중 친구와 고민을 나누다 프로그램을 2개로 나누는 2번 방법을 택했다.

물론 DB를 사용해 갱신 유저 목록을 저장하고 꺼내 사용하면서 api 실패지점까지 사용하는 방법이 있지만, DB를 사용하는 것이 좋은 방법은 아니라는 생각을 했다.

 

그래서 내가 생각한 방법은 Message Queue (RabbitMQ)를 사용하는 방법이다.

Broker가 갱신해야할 유저 목록을 찾아내고 queue에 저장하고, Consumer가 queue에서 유저를 꺼내 api 횟수에 맞춰 갱신한다. 필요했던 기능은 다음과 같다.

 

    1. kafka처럼 대형 분산처리가 필요하지도 않았으며, 가벼운 message queue가 필요했다.

    2. 지연시간이 짧고 프로그램 종료 이후에도 queue 내용이 저장되길 바랬다.

    3. consumer가 ack를 날리지 않으면 다시 queue로 넣을 수 있는 기능이 필요했다.

 

위와 같은 이유로 RabbitMQ를 선택했고 queue에 중복 입력을 방지하는 플러그인이 있어 테스트 중에 있다.

만약 사용이 불가능하다면, 직접 처리를 해야하긴 할 것 같다.

 

추가적으로 백준 사이트에서 각 문제에 대한 크롤링은 금지하고 있지 않은 것을 확인했다.

초기 APIs를 이용해 문제 목록을 가져오는 것이 참 어려운 일이었는데, 크롤링을 통해 가져오면 간단해질 것이라 생각했다.

 


2. Croller 공부 및 DB연동


문제 난이도는 로그인을 하여 solved ac 티어 이미지 이름의 끝자락 1~20의 숫자로 판별하려고 했다.

(1은 브론즈5, 2는 브론즈4...)

 

그러나 처음 작성한 BS에서 티어 정보 사진을 가져오지 못하는 것을 확인했고 페이지 로딩 이후 추가적인 javascript가 실행되서 그런지 동적이라 잡아오지 못하는 것 같았다.

 

Selenium으로 변경하여 개발을 시작하였고 페이지 호출 이후 1초의 간격을 주었더니 제대로 긁어오지 못하는 경우가 생겨 2초 간격으로 크롤링을 하도록 하였다.

 

추가적으로 백준문제는 1,000번부터 ~ 약 30,000번의 문제로 이루어져 있는데 아직 난이도가 설정되지 않은 문제거나, 중간에 빠져있는 번호가 있어 오류가 발생했었다.

 

바로 위 사진에 1320번이 없는 것을 확인할 수 있다. 이처럼 몇가지 오류를 해결하고 크롤링한 결과를 sql문으로 가져오도록 구현하였다. 아래 영상과 같이 크롤링이 잘 되는 것을 확인했다.

 

sql은 우선 테스트를 위해 txt파일로 저장하도록 하였고 dump 파일로 변경해 db에 저장하려고 한다.

추가적으로 크롤링 실패시 오류를 에러 로그.txt 파일에 저장하도록 하였다.


3. RabbitMQ


 

1번에서 이야기한 이유로 RabbitMQ를 사용하였고 이를 설치하고 공부하였다.

오래된 툴이라 그런지 document가 친절하고 설치법과 튜토리얼 모두 잘 되어있어 배우기 수월했다.

 

우선 간단하게 정보를 주고 받는 튜토리얼까지 완료한 상황이고 db와 연동을 시작할 예정이다.

자세한 내용은 아래 링크에서 다룬다.

Rabbit MQ 다루기

 

[RabbitMQ] 설치부터 튜토리얼까지

바보같이 pip install pika만 하고 rabbitMQ 자체를 설치하지 않았다...ㅎㅎ 윈도우 기준으로 choco를 설치하고 난 뒤에 아래 코드를 powershell에서 입력하면된다.(choco 설치 방법 및 초코 설명 링크)(혹은

readble-ko.tistory.com