BOJ 크롤러를 만들며

글 목록

2025. 05. 04.

백준 문제 푼 것을 아이디 기반으로 크롤링하는 프로젝트를 만들면서 아래와 같은 생각을 했다.

1

이 프로젝트를 진행한 첫 번째 이유는 새로 만든 백준 계정으로 지금까지 푼 문제들을 정리하기 위해서였다. 아직 200 문제도 풀지 않았기 때문에 사실 제출한 답안 리스트를 쭉 훑으면서 손으로 한땀한땀 자료를 만들어도 시간이 많이 걸리지는 않았을 것이다. 그리고 어쩌면 이 편이 크롤링을 하는 코드를 어떻게 짜는지 자료를 찾아보면서 크롤러를 직접 만드는 것보다 시간이 덜 걸렸을 수도 있겠다. 옛 말에 개발자는 30분이면 손으로 끝낼 작업을 3초만에 완료하기 위해 2시간 동안 코드를 짜는 사람이라고 하지 않았던가.

이런 상황에서는 내가 휴먼 크롤러가 되어 자료를 직접 모으는 데에 시간을 쓰는 것과 크롤러 코드를 짜는 데에 시간을 쓰는 것 중 어떤 것이 더 시간을 가치있게 쓴 것인지 고민해볼 수 있었다. 크롤링 코드를 짠 것을 옹호하자면, 코드를 짜는 데에 시간이 더 오래 걸렸더라도 앞으로 비슷한 크롤링 작업을 할 일이 있으면 이 크롤러를 재사용할 수 있다고 주장할 수 있겠다. 수작업 진영을 옹호하자면, 한 번 자료를 다 정리하고 나면 앞으로 문제 풀때마다 조금씩만 수동으로 자료를 업데이트 해도 되기 때문에 크롤러를 만드는 건 닭 잡는 데에 소 잡는 칼을 쓴 것이고 이런 상황에서는 그냥 손으로 작업하는 것이 더 합리적인 판단이라고 말할 수 있겠다.

그런데 ai 툴들이 나오고 나서는 이야기가 달라진것 같다. 내가 푼 문제 리스트를 확인할 수 있는 링크를 던져주고 여기에서 '크롤링해라'라고만 이야기했는데, cursor가 풀이 번호와 문제 번호, 풀이 언어를 리스트로 정리해서 저장해주는 코드를 바로 짜줬다. 심지어 한 페이지에는 20개밖에 기록이 없으니 다음 페이지로 넘어가면서 전체 기록을 정리해달라고 요청하니 이 코드도 바로 짜줬다. 원래라면 적어도 몇 십 분은 프로젝트를 초기화하고 html을 뜯어보면서 필요 정보를 어떻게 추출할지 코드 짜보고 하는 데에 썼을 텐데, 지금은 그냥 돌리면 작동하는 코드가 1분이면 나온다. 이제는 boj 문제를 푼 기록을 정리하기 위해 휴먼 크롤러가 될 이유가 전혀 없다. 손으로 수동 크롤링을 하면 내 인생의 몇 십 분을 그냥 바닥에 던지는 거라고 볼 수 있는 것이다.

2

크롤러 프로젝트를 만든 두 번째 이유는 여러 사람들의 풀이 기록을 긁어올 일이 생겼기 때문이다. 최근에 '오늘 문제풀이 완료'라는 오픈카톡 방을 만들어서, 한 달에 백준 문제를 적어도 10 문제를 풀 사람들을 주변에서 모집했다. 이 방에 모인 사람들이 문제를 잘 풀고 있는 것을 어떻게 확인할까? 바로 방에 있는 사람들의 백준 아이디를 가지고 풀이 내역을 확인해보는 것이다. 물론 사람이 많지 않으면 어차피 최근 한 달 기록만 월말에 확인하면 되니까 직접 백준 프로필을 찾아서 들어가보는 것도 괜찮겠다. 하지만 이 방은 얼마든지 인원이 늘어날 수 있으니 크롤러를 짜두면 매우 유용할 것도 분명하다.

예전이었으면 풀이 내역을 전체 크롤링하는 코드를 짜뒀으니 그냥 이걸로 매 달 전체 풀이 내역을 받아온 다음 이번 달 풀이 수를 세는 코드를 별도로 짰을 지도 모르겠다. 어차피 boj 서버는 이미 충분히 많은 트래픽을 감당하고 있을 테니 내가 요청을 좀 더 보낸다고 해도 큰 문제가 없을 것이고, 크롤러 코드가 몇 분 더 돈다고 해서 내가 원하는 기능을 구현하는 데에 전혀 지장이 없으니 그냥... 귀찮게 기존 코드를 수정해서 특정 달에 제출된 풀이만 뽑아오는 기능은 추가할 필요는 없겠다고 판단했을것 같다.

그런데 지금은 cursor에 yyyymm꼴의 arg를 넣어서 이 기간에 해당하는 풀이 내역만 저장하고, 어차피 풀이는 날짜로 정렬되어 있으니 해당 기간 이전에 작성한 풀이가 나오면 크롤링을 멈추도록 기능을 추가해달라고 요청하니 또 곧바로 작동하는 코드를 짜줬다. 이렇게 쉬울 거면 코드를 안 짤 이유를 찾아서 내 게으름을 합리화하는 데에 쓸 에너지를 cursor에 딸깍 해서 기능 추가하는 데에 쓰면 되는 수준 아닌가? 진짜 무서운 세상이다.

3

위의 크롤러를 좀 더 개선한다면 제출된 풀이의 id를 기반으로 이미 기존에 크롤링한 정보를 다시 긁어오지 않도록 할 수도 있을 것이고, 크롤링한 정보의 포맷에 대한 버전을 관리해서 크롤러가 긁어오는 풀이의 포맷과 기존에 저장되어 있는 기록의 포맷이 맞지 않을 경우 다시 전체 크롤링을 돌리는 기능을 구현하는 것도 가능할 것이다.

어쩌면 새로운 시대의 개발자가 할 줄 알아야 하는 것은 위와 같은 기능 개선 계획을 짜는 것이 아닐까? 이제 간단한 코드 작성(혹은 생성)은 누구나 할 수 있는 것이 되었으므로 이걸로는 차별화를 하기는 어려울 것이다. 하지만 계획은 조금 다르다. 이 영역은 어쩌면 바이브 코딩만으로 프로젝트를 만드는 비개발자들은 아직 접근하지 못하는 영역일 수도 있겠다는 생각이 든다. 프로젝트를 개선한다면 어떻게 개선할 수 있을지 상상할 줄 알아야 하고, 이러한 개선이 실질적으로 어떤 이점을 가져다 주는지(혹은 들이는 품에 비해 큰 이득이 없는지) 판단도 할 줄 알아야 하는데, 코드를 짤 줄 모르고 생성된 코드를 보기만 하는 입장에서는 어떤 코드가 왜 생성되지 않았는지, 지금 눈 앞에 있는 코드가 최선인지 알 방법이 없기 때문이다.

글 목록