[BOJ] 파이썬 웹 크롤러의 문제 티어 크롤링 에러 해결

작성:    

업데이트:

카테고리:

태그: , , ,

작성 목적 및 오류 파악

파이썬 웹 크롤러가 어느 순간 고장이 나서 왜 그런가 알아보니 크롤링 과정에서 문제의 티어를 체크하는 solved.ac 사이트에서의 크롤링이 문제가 되었다. 기본적으로 백준 사이트에서 문제를 크롤링하면 아래와 같다.

image

body의 모든 태그가 잘 보임을 확인할 수 있다. 하지만 티어의 태그를 끌고 오는 solved.ac의 사이트를 크롤링하면 아래와 같다.

image

head 태그의 내용이 잘 나오다가 어떤 태그를 기준으로 U+ 같은 유니코드 방식?으로 깨지면서 하위의 body 태그의 모든 태그들이 보이지 않았던 것이다. 이상한 점은 크롤러나 BeautifulSoup의 문제라면 백준 사이트에서도 오류가 발생해야 하는데, solved.ac에서만 문제가 발생한다는 점이다.


뭐가 문제일까?

그래서 solved.ac에서 무언가 크롤링을 방어하는 과정을 추가한 것이 아닐까 싶었다. 물론 이를 뚫어내는 것이 기존 코드를 활용하는 가장 효율이 좋은 대안이겠지만, 그냥 크롤링이 잘 되고 있는 백준 사이트에서 로직을 통해 해결해보고자 했다.


해결 과정

기존 방식

기존에 문제의 티어를 가져오는 방식이다.

image

solved.ac에서 문제 번호를 검색하면 문제 티어 이미지의 alt가 사진처럼 Silver II 같은 방식으로 클래스와 티어를 보여줬던 것이다. 이를 분리해 로직적으로 풀어나가는 방식이었다.


왜 백준에서 바로 하지 않았는가

백준에서도 문제의 티어를 확인할 수 있다. 하지만 내가 그렇게 하지 않았던 이유는 끌어오는 데이터가 직관적이지 않았기 때문이다.

image

대놓고 어떤 티어인지 알려주지는 않는다.


Trouble Shooting

완전히 방법이 없는 것은 아니다. 문자열을 어느 정도 처리는 해주어야겠지만 img src의 링크에 최하위에 숫자로 티어를 구분할 수 있다.

Bronze V를 1로, Bronze IV를 2로 하며 난이도가 높아짐에 따라 순차적으로 숫자를 높여주기 때문에 이를 통해 티어를 계산하는 방식으로 변경해볼 것이다.


  Bronze Silver Gold Platinum Diamond
5 1 6 11 16 21
4 2 7 12 17 22
3 3 8 13 18 23
2 4 9 14 19 24
1 5 10 15 20 25

위와 같은 방식으로 구성되기 때문에 5로 나눈 몫과 나머지로 계산해주면 되겠다.


실패

image

백준은 문제의 난이도를 선택적으로 나타낼 수 있도록 옵션을 설정하기 때문에 ::before로 난이도를 화면에 렌더링한다. 그래서 크롤링을 하면 기본 설정인 문제 난이도가 없는 html 파일이 파싱되어서 문제의 난이도를 파악할 수 없었다.


조금은 아날로그로

도저히 대안은 생각이 안 나고, 문제를 해결하지 못해 포스팅은 미뤄지니 답답함이 생겼다. 그래서 처음에 방법을 시도해보고 안 되면 시도하려 했던 차선책으로 개발하기로 했다. 문제 난이도를 입력으로 받는 것이다.

image

10단위를 클래스로 해서 브론즈는 10, 실버는 20, 골드는 30… 순으로 하고, 티어 I, II, III… 는 각각 1, 2, 3…으로 해서 실버3은 ‘23’, 골드5는 ‘35’ 식으로 간단하게 입력하는 방식으로 했다.


난이도 입력 문제 클래스와 티어
image image

이렇게 2주 넘게 미뤄온 포맷터 수정을 마쳤다.

댓글남기기