수백 장을 올렸는데 색인은 열몇 장이었다
사이트맵에 877장을 올렸는데 검색엔진이 색인한 건 14장이었습니다. 원인을 하나씩 지워가며 찾은 기록과, 도중에 제가 잘못 짚었던 것들.
사이트맵에 877장을 올렸습니다. 검색엔진이 실제로 색인한 것은 14장이었습니다.
1.6%입니다. 나머지 863장은 "발견은 했지만 크롤하지 않음" 또는 "크롤했지만 색인하지 않음" 상태로 남아 있었습니다.
원인을 찾는 데 시간이 꽤 걸렸고, 그 과정에서 제가 잘못 짚은 것이 여러 번 있었습니다. 그 오답들이 오히려 쓸모 있을 것 같아 순서대로 적습니다.
오답 1: "페이지가 얇아서"
가장 먼저 의심한 것은 내용의 얄팍함이었습니다. 실제로 값만 다르고 구조가 같은 페이지가 수십 장 있었고, 재보니 본문 글자 수가 전부 똑같았습니다. 1,533자로 완전히 동일. 숫자만 바뀐 틀이었으니 당연한 결과입니다.
"이게 원인이구나" 하고 정리 계획을 세웠는데, 확인차 색인된 14장의 목록을 봤더니 그중 대부분이 바로 그 얇은 페이지들이었습니다.
가설이 정반대로 뒤집혔습니다. 얇아서 색인이 안 된 게 아니라, 얇은 페이지가 오히려 색인된 쪽이었습니다. 검색엔진은 같은 틀의 페이지 수십 장 중 대표 몇 장만 남기고 나머지를 버리는 방식으로 처리하고 있었습니다.
오답 2: "없는 주소가 200을 주고 있어서"
다음으로 의심한 것은 소프트 404였습니다. 존재하지 않는 주소에 200을 주면 검색엔진은 "이 사이트는 모든 주소가 같은 내용"이라고 판단하고 크롤을 줄입니다.
확인해 봤습니다.
$ curl -o /dev/null -w '%{http_code}' https://example.com/wp-admin/
200
없는 주소인데 200. "찾았다" 싶었습니다.
그런데 이게 틀린 확인이었습니다. 서버 코드를 읽어 보니 소프트 404를 막는 규칙이 이미 있었고, 그 규칙은 요청 헤더에 Accept: text/html이 있을 때만 동작하게 되어 있었습니다. 브라우저와 검색엔진 크롤러는 이 헤더를 보내지만, 기본 curl은 보내지 않습니다.
헤더를 붙여 다시 확인했습니다.
$ curl -H 'Accept: text/html,application/xhtml+xml' \
-o /dev/null -w '%{http_code}' https://example.com/wp-admin/
404
정상이었습니다. 제 확인 방법이 틀렸던 것뿐입니다.
교훈: 크롤러의 동작을 확인할 때는 크롤러처럼 요청해야 합니다. 명령 한 줄로 확인하고 "원인 찾았다"고 결론 내리기 전에, 그 명령이 실제 요청과 같은지부터 봐야 합니다.
오답 3: "홈에서 링크로 안 닿아서"
세 번째 가설은 내부 링크였습니다. 사이트맵에만 있고 어디서도 링크되지 않은 페이지는 검색엔진이 중요하지 않다고 판단합니다.
마침 링크 경로를 검사하는 도구가 있어서 돌렸더니 이렇게 나왔습니다.
홈에서 도달 1개 (HTML 0장 확인)
링크로 닿지 못하는 페이지 876개 — 사이트맵에만 있습니다
876장이 고아라니, 이거야말로 원인 같았습니다.
그런데 출력의 HTML 0장 확인이 걸렸습니다. 한 장도 못 읽었는데 어떻게 판정을 했을까? 도구를 열어 보니 기본값이 로컬 미리보기 서버 주소였고, 그 서버가 떠 있지 않아 전부 실패한 상태에서 "못 닿았다"고 센 것이었습니다.
실제 주소를 지정해서 다시 돌렸습니다.
홈에서 도달 1575개 (HTML 1575장 확인)
사이트맵 전 페이지가 홈에서 링크로 도달 가능 ✓
멀쩡했습니다. 세 번째 오답이었습니다.
그래서 진짜 원인은
세 가설이 모두 빗나가고 남은 것은 크롤 빈도 자체였습니다.
색인된 14장의 마지막 크롤 날짜를 보니 대부분 한 달 전에 몰려 있었습니다. 그 뒤로는 홈 한 장만 최근에 크롤됐고 나머지는 방치 상태였습니다. 즉 색인이 안 되는 게 아니라 크롤을 안 오고 있었던 것입니다.
크롤 예산을 갉아먹던 것 두 가지는 이미 조치된 상태였습니다.
- 배포할 때마다 모든 페이지의 수정일이 그날로 찍혀서, 매 배포마다 "전 페이지가 바뀌었다"는 신호를 보내고 있던 문제
- 없는 주소가 200을 주던 문제(위의 오답 2에서 확인했듯 이미 고쳐져 있었음)
조치 이후 크롤이 다시 오기 시작한 흔적은 보였지만, 색인 숫자가 움직이려면 시간이 더 필요한 단계였습니다.
지금 상태와 판단
지금은 기다리는 구간이라고 정리했습니다. 손댈 게 없어서가 아니라, 손대면 안 되는 시점이기 때문입니다.
여기서 흔한 유혹이 있습니다. 얇은 페이지를 대량으로 지우는 것입니다. 저도 그러려다 멈췄습니다. 이유는 두 가지입니다.
- 이미 색인된 14장 중 대부분이 그 얇은 페이지들입니다. 지우면 있는 것마저 잃습니다.
- 조치의 효과가 아직 지표에 반영되지 않았습니다. 효과를 보기 전에 다른 변수를 넣으면, 나중에 무엇이 작용했는지 알 수 없게 됩니다.
그래서 날짜를 정해 두고 그때 다시 보기로 했습니다. 변수를 하나씩만 바꾸고 결과를 기다리는 것, 이게 결국 제일 빠릅니다.
정리하면
세 번 헛짚으면서 배운 것을 남깁니다.
- 가설을 세웠으면 반대 증거부터 찾으세요. "얇아서 색인이 안 된다"는 가설은, 색인된 목록을 5분만 봤으면 바로 깨졌을 것입니다.
- 확인 명령이 실제 상황과 같은지 보세요. 헤더 하나 차이로 결론이 정반대가 됐습니다.
- 도구의 출력에서 이상한 숫자를 그냥 넘기지 마세요. "0장 확인"이라는 말이 붙어 있었는데도 결론만 읽고 876장이 고아라고 믿을 뻔했습니다.
- 효과를 기다려야 할 때는 기다리세요. 조치와 조치 사이가 짧으면 무엇이 통했는지 영영 모릅니다.