최근에 없는 시간을 쪼개서 의미있는 것을 하나 만들어보자, 하는 마음으로 며칠간 파이썬으로 l.cublr.com 이라는 사이트를 만들었다. 유명 커뮤니티 자유게시판의 최신 3시간 글을 긁어서 조회수 순으로 나열하는 사이트다.
크롤링하는 사이트의 목록은 다음과 같다.
- 82cook.com
- clien.net
- ddanzi.com
- ppomppu.co.kr
- te31.com
제작 상세
만들게 된 동기… 라고 하기에는 거창하지만, 어쨌든 만들게 된 이유는 다음과 같았다.
- 조회수 순으로 할 경우 한 사이트가 독식하는 경우가 많다.
- 크롤링 데몬의 갱신이 늦은 편인지, 갱신하는 시간이 꽤 걸린다.
- flask와 파이썬에 대해 조금 더 심오하게 배우고 싶다.
- 올바른 html의 사용, 그리고 angularjs 등의 js 프론트엔드 기술을 배우고 싶다.
이 정도의 이유가 있겠다. 현재 이런 유명한 사이트로는 best.mqoo.com이 있는데, 이 사이트가 굉장히 좋은데 문제는 위 항목의 1, 2번에 걸릴 때가 있다는 것.
현재 언어는 python3이며 다음과 같은 모듈이 존재한다.
- 크롤링 데몬: pydaemon + beautifulsoup를 이용한 크롤러
- api/view 서버: flask + sqlalchemy 를 사용
- html: bootstrap
그럭저럭 보는 것에는 지장이 없고 갱신도 빠른 편이라 꽤 만족스럽게 사용할 수 있었다. 다만 디자인이 문제일 뿐.
개선하고 싶은 부분
이제 만들고 난 다음의 목표를 생각해 보자. 사실은 이 부분 때문에 이걸 한번 만들어보기로 결정한 것인데, 어쨌든 다음과 같다.

평점을 사용한 새로운 정렬 기준
조회수를 사용하여 정렬할 경우 다음과 같은 문제점이 있다.
- 조회수가 높다고 해서 가치가 있는 글은 아니다.
- 사이트마다 유저 수가 다르기 때문에 조회수를 사용하여 측정할 수 없다.
예를 들면 te31.com의 경우 기본 조회수가 낮은 편이라, 1~2페이지에서는 재미있고 가치있는 글이 절대 노출이 되지 않으며, ddanzi.com에서는 기본 조회수가 높아 아예 상위권을 독식해버리는 상황이 자주 발생한다. 따라서 이런 문제점을 해결할 방식으로 글에 다른 기준인 평점을 부여하여 이 기준으로 정렬하는 것이 나아 보인다. 일단 생각하고 있는 방법은 매우 간단하게, 다음과 같다.
- 사이트의 최근 3시간 글들의 평균 조회수, 평균 댓글 수를 계산
- 이 내용으로 글의 조회/댓글 평준화
- 평준화된 수치로 글에 평점 부여
유저가 적은 사이트이지만 충분히 재미있고 가치있는 글이라면, 평균 수치보다는 더 높은 것이 맞을 테니까 큰 문제는 없어 보인다.
크롤링 데몬의 속도 증가
현재 크롤링하는 부분의 루프를 단순하게 써보면 다음과 같다.
- 한 페이지 크롤링 후 3초간 대기
- 모든 사이트 크롤링 후 150초간 대기
글이 활발하게 올라올 경우 1번에서 문제가 생긴다. 1번 페이지 끝에 있던 부분이 다음 크롤링 때 2번 페이지 위쪽에 배치되는 경우가 생기게 된다. 이 부분은 파이썬 set을 사용해서 중복 오브젝트를 제거하도록 했지만, 별로 깔끔한 방법은 아닌 것 같다. 그렇다고 더 좋은 방법이 떠오르지는 않고. 사실 제일 좋은 방법은 게시판을 긁어오는 것이 아니라, 게시글 자체를 긁어오는 방법일 것이다. 최신글의 id에서 계속 1씩 빼면서 원하는 시간의 글까지 긁어오는 것. 이렇게 되면 최신 30페이지를 긁어오는 것이 아니라 약 1500개 글을 긁어야 되서 좀 양아치스럽기도 하고, 트래픽 테러범 같기도 해서 별로 마음에 들지는 않는다.
그래서 생각해 본 타협안은 다음과 같다. 사이트 숫자만큼 쓰레드를 생성해서 한 번에 긁어오는 것. 요거는 몇 가지 테스트를 해 봤는데 큰 문제는 없을 것 같다. 이렇게 적용할 경우 대기시간이 급격히 짧아질 것이므로, 2번 딜레이가 150초보다 조금 더 길어져야 할 것이다.
flask + nginx + uwsgi 속도 증가
이거는… 이유를 잘 모르겠는데, w.cublr.com에는 접속이 굉장히 빠른데, l.cublr.com은 속도가 느린 것으로 보아 아무래도 uwsgi의 문제같은 느낌이 든다. 사실 이쪽은 봐도 잘 모르겠어서… 공부 좀 해봐야 알겠지만, 속도가 개선이 되야 조금 더 쾌적할 것 같다. mysql이 아니고 sqlite3라서 그런가, 아무튼 이건… 잘 모르겠다.
뭐 개선해야 할 부분은 이 정도 같다.
하고 싶은 것들
이걸로 일차적인 사이트 구현은 대충 끝난 것 같다. 그러면 이걸 사용해서 조금 더 뭔가를 추가하고 싶은데, 그게 바로 이런 것들이다.
손쉬운 사이트의 추가
예를 들면 이런 것이다. 지금은 사이트를 추가하려면, 그 사이트의 정보를 담은 클래스를 생성해서 사용해야 한다. 하지만 이러면 프로그램의 수정이 따르므로, 이런 설정은 yaml등을 이용해서 손쉽게 추가하고 싶다.
굉장히 표준스러운 rest api 구현
제목대로 많이 표준스러운 rest api를 구현하고 싶다. 예를 들면 페이지 쿼리의 경우 from, to같은 이름의 쿼리스트링을 사용하는 것이 아니라, Range 헤더를 사용해서 한다거나 해서, api이름과 대강의 설명만 듣고도 누구나 프론트를 붙일 수 있도록 말이다. 그게 된다면 angularjs를 공부하는 느낌으로 나도 직접 프론트를 붙여보고 싶다.
css 수정
현재 사이트는 bootstrap table을 사용해서 만들었는데, 테이블을 사용하여 만들고 싶지 않다. 뭐 table 태그는 반드시 사용하지 말아야 하며, div를 사용해야 한다는 그런 내용에 동의를 해서 그런 것은 아니고, 그래도 스타일시트를 적용하지 않았을 때 이 사이트가 ul, li를 사용해서 이런 식의 목록으로 보였으면 좋겠다.

이 상태에서 스타일시트를 적용했을 때 대강 원하는 모습으로 나오도록 수정은 적당히 했으나… padding, position, float 등을 이용해서 모양을 그렇게 만들어가지고, 이게 제대로 된건지는 조금 걱정이 든다. 이것도 취미삼아 공부를 좀 하면은… 잘 할수 있지 않을까?
뭐 어쨌든 앞으로 계속 수정은 진행될 것이다.