아파치 로그를 분석해 블로그 트래픽 소모 양상을 알려 주는 좋은 서비스가 닷홈에 있었다. ( 내아이디.dothome.co.kr/weblog 로 가서 보면 된다.) 그래서 알 수 있게 됐다. 내 블로그 트래픽을 잡아 먹는 주범이 누군지 말이다. 검색 엔진들이었다. 사람이 하루 1000회 내외 방문하는 내 블로그엔 검색 로봇들은 하루 6000~1만 회 이상씩 방문하고 있었다. 제기랄!

검색 로봇

검색 엔진에 색인돼 있는 웹페이지들을 사람이 긁어 모은다고 생각하진 않을 거다. 컴퓨터가 긁어 모은다. 이 컴퓨터가 내 웹사이트를 긁어 간다고 치자. 이걸 크롤링(Crawling)이라고 부른다. 크롤링 하는 것은 사실 그냥 사람이 내 웹사이트에 방문해서 웹페이지를 보는 것과 같은 행위다. 사람은 웹사이트를 이용하고, 검색 엔진의 로봇은 사이트를 긁어가서 검색 엔진에 저장한 뒤 분석한다는 점만 다르다.

사람은 웹페이지를 훑어 보는 반면, 검색 엔진의 로봇은 웹페이지 접속이 완료되는 순간 그냥 다른 곳으로 이동해 버리면 그만이기 때문에 사람보다 훨씬 더 많은 페이지를 짧은 시간에 볼 수 있다. 이 말은? 그렇다. 훨씬 더 많은 트래픽을 유발할 수도 있다는 이야기가 된다.

그래서 검색 엔진 로봇들은 사이트에 부담을 주지 않을 정도로 알아서들 조절을 하는 알고리즘을 갖고 있다(고들 주장 하는데 구글만 그런 것 같다). 자, 검색 엔진 로봇과 트래픽에 대한 간단한 설명 끝.

괴물 빙봇

검색 로봇이 트래픽을 왕창 소모하고 있는 걸 처음 눈치를 챘던 건 BingBot 덕분(?)이었다. Bing은 MS의 검색 엔진이다. 웹 로그의 최다 유저에이전트(UserAgent. 방문자 정보의 일부. 보통 브라우저와 운영체제에 관한 정보가 적혀 있다. 정상적인 로봇의 경우 자기가 로봇이라고 여기에 적어 둔다)에 빙봇이 찍혀 있었다. 전체 방문의 70%를 빙봇이 차지했다. (구글은 신사다.) 그 때가 트래픽 초과 문자를 자주 받았을 때다. 빙은 한국에선 다음 검색과 제휴를 맺고 있기 때문에 빙으로 검색해 봐야 다음 검색 결과가 나온다. 따라서 나에겐 쓸모없는 검색 엔진이다. 영어 블로그가 있긴 하지만 아직 글은 두 개에 불과하다.

심지어 영어로 빙봇 트래픽 문제에 관해 검색을 해 보니 빙봇에 대한 원성을 상당히 접할 수 있었다. 나는 검색 로봇이 트래픽 조절도 못하는 게 괘씸해서 빙봇을 차단해 버렸다. robots.txt에 아래처럼 적었다. (robots.txt는 사이트 최상단에 두는 파일이다. 검색 엔진은 이 파일을 참고해서 해당 사이트 크롤링 정책을 정한다. 참고한다는 말은 참고만 할 뿐이라는 말이기도 하다. 그러니 이걸로 보안조치나 강제조치 같은 걸 할 수는 없다.)

User-agent: bingbot
Disallow: /

일단 트래픽 초과 문자는 안 오기 시작했다.

빙봇 차단 조치 후 얼마 안 있어 다시 트래픽 초과 문자가 왔다. 이번엔 Daumoa라는 다음 봇이었다. 이 다우모아라는 놈도 거의 빙봇처럼 트래픽을 쓸어가고 있었다. 빙은 트래픽을 전혀 가져다 주지 않지만 다음은 트래픽을 그래도 주긴 하므로 차단하진 않고 방문 주기를 길게 늘리라고 알려 줬다.

User-agent: Daumoa
Crawl-delay: 10

Crawl-delay는 검색봇이 한 페이지에서 다음 페이지로 넘어갈 때 간격을 몇 초로 할지 알려 주는 항목이다. 일단 10으로 했다.

로봇을 혼란시키는 다양한 조합의 태그 목록 문제

다우모아까지 처리한 뒤 트래픽을 확인하러 웹 로그 서비스에 들어갔는데 호랑이 나간 골에 여우가 왕이라고 이번엔 바이두스파이더가 트래픽을 휩쓸고 있었다. 바이두(Baidu)는 중국의 최대 검색엔진이다. 다행히 바이두스파이더는 빙봇만큼 무지막지하진 않았다.

바이두스파이더는 태그의 글목록 페이지를 열심히 긁어 가고 있었다. 내 블로그 태그 목록은 a 태그 목록, b 태그 목록을 볼 수 있을 뿐 아니라 a와 b 태그를 동시에 가진 목록도 볼 수 있게 해 놨다. 태그 개수가 많아지면 기하급수적인 조합이 생기는데, 바이두스파이더는 그걸 전부 긁어가고 있었다. 제기랄.

그래서 태그 목록을 보는 방식을 일반적인 방식으로 변경했다. 한 번에 한 태그의 목록만 나오도록 말이다. 태그 두 개 이상의 목록을 요청하는 경우엔 빈 화면만 나오도록 했다.

wp bot analytics 플러그인

바이두스파이더가 태그의 미로를 해매고 있다는 사실을 알 수 있었던 건 워드프레스의 봇 추적 플러그인 덕이다.

다우모아까지 저러는 걸 확인하고 나니 로봇이 대체 트래픽을 얼마나 잡아먹는지 궁금해졌다. 워드프레스 플러그인이 있겠거니 생각하며 검색을 해 봤다. 그래서 딱 찾게 된 것이 wp bot analytics다.

이 플러그인은 데이터를 구글 아날리틱스에 수집한다. 그래서 장점이 생긴다.

  1. 내 블로그의 용량을 소비하지 않고 많은 데이터를 축적할 수 있으며,
  2. 어떤 로봇이 어떤 페이지를 봤는지 알 수 있고,
  3. 구글 아날리틱스의 기능들을 이용해서 데이터를 정리할 수도 있다.

바퀴를 새로 만들지 않는 좋은 플러그인이다. 참고로 기존의 사람용 아날리틱스 말고 봇 전용 아날리틱스 프로필을 따로 만들어서 사용했다. 사람 데이터랑 섞이면 안 되니까 말이다.

플러그인을 설치하고 하루 지난 후 확인해 보니 세상에 하루에 봇만 6천 회 이상 방문을 하고 있었다. ㄷㄷ 앞서 말했듯 사람의 하루 방문수는 대략 1천 내외다. 게다가 봇들에겐 주말도 없다.

이쯤 되니 Daumoa에게 한정할 게 아니라 모든 봇의 크롤링 빈도를 늦추는 게 나을 것 같다는 판단이 들었다. 그래서 아래 코드를 robots.txt에 넣었다.

User-agent: *
Crawl-delay: 10

Daumoa를 *로 변경해 robots.txt를 준수하는 모든 신사적인 로봇이 적용할 수 있도록 한 거다.

?print=yes 문제

내 블로그의 모든 글은 ?print=yes 파라미터를 붙인 채 들어오면 인쇄 스타일로 글이 보인다. js를 켜지 않은 사람을 위한 배려였던 것인데 검색엔진들이 저 링크를 따라가고 있을 줄은 몰랐다. 그런데 ?print=yes가 하는 조치는 클래스를 하나 넣는 것밖에 없기 때문에 ?print=yes?print=yes?print=yes 하는 식으로 바이두스파이더는 URL 무한반복 테크를 타고 있었다. 다른 봇들도 비슷했다. 구글만 안 그러는 것처럼 보였다. 그래서 결국 플러그인의 힘을 빌리기로 결심! 코드를 짰다.

wp bot analytics 플러그인은 유저에이전트 문자열을 바탕으로 봇을 판단하는 데이터를 갖고 있다. 그걸 빌려다가 봇인지 아닌지 판단할 수 있도록 했다. 그리고 봇이 들어오는 경우 print 파라미터를 포함한 URL을 호출하면 아무것도 출력하지 않도록 조치했다.

아울러 물음표 여러 개가 붙는 경우에도 아무 것도 안 나오게 처리했다.

중간 결과

이렇게 하고 나서 이틀 동안은 bot의 트래픽 공격이 사라졌다. 이후로는 로봇이 하루에 800~2,200건 정도만 방문을 하게 됐다. 아래는 통계 그래프.

그런데 왠걸, 이틀이 지나고 나니까 다시 트래픽 공격이 시작됐다. 이번엔 네이버봇이었다. 아래 이미지를 보라.

트래픽이 다시 예전 수준으로 늘었고 네이버봇의 비중이 70퍼센트다. 그래서 robots.txt를 추가로 고쳤다.

User-agent: *
Crawl-delay: 288

크롤 딜레이를 288로 하면 이론적으론 하루에 한 봇이 페이지를 최대 300개밖에 못 긁어 갈 것이다. 내 웹사이트를 네이버봇이 긁을 때 봇을 하나로 가정하고 긁는 것인지, 여러 개로 가정하고 긁는 것은지 확실치 않은 점, 그리고 과연 네이버봇이 이 항목을 이해하고 지키는지 이런 게 확실치는 않지만 어쨌든 저렇게 해 두고 실험해 보기로 했다.

일주일쯤 후 결과를 적으려고 한다. 만약 네이버봇이 저 항목을 지키지 않는다면 PHP단에서 네이버봇을 제재하는 코드를 넣을 생각이다.

네이버 봇 처단

일주일이 흘렀다. 네이버봇은 계속 폭주했다. 그래서 처단하기로 결심했다. 테마의 single.php 파일 상단에 아래 코드를 넣었다.

if( strstr(strtolower($_SERVER['HTTP_USER_AGENT']), 'naver') ){
    // if naver bot and 10 days past, exit;
    if(strtotime(get_the_date()) < time()-60*60*24*10){
        exit;
    }
}

위 코드를 single.php 파일의 get_header() 코드가 나오기 직전 위치에 삽입하면 발행한 지 10일이 지난 글에 네이버 봇이 방문한 경우에 차단해 버린다.

Chrome에서 user agent 문자열을 바꿔치기해서 코드가 제대로 작동하는지 테스트해 볼 수 있다. F12 키를 눌러 개발자 도구를 연 뒤, esc 키를 누르면 하단에 뭐가 나타난다. 여기서 Emulation 탭을 고르면 좌측에 User Agent라는 항목이 있는데, 이걸 고른 뒤 Other를 선택하고 거기에 naver라고 적어 주면 된다.

다시 일주일 뒤에 네이버 봇 처단 결과를 적도록 하겠다.