서치 콘솔이 공시 페이지를 모른다고 해서 확인한 것들
네이버 서치어드바이저의 "robots.txt에 의해 차단" 18건에서 시작해, 구글 서치 콘솔의 표본 조회와 페이지 두께 실측까지 이어진 이틀
공시 요약 서비스에서 검색 유입이 거의 없다. 한 주에 7세션 정도고, 서치 콘솔에 찍힌 클릭은 30일 내내 0이다. 이번에는 그 이유를 하나씩 확인했다. 결과가 나온 이야기는 아니고, 막혀 있던 것을 푼 이야기다.
하려던 것
네이버 서치어드바이저에 경고가 떴다. 날짜와 분류가 붙은 목록 주소 18건이 “robots.txt에 의해 수집 차단”이라는 내용이었다. 나는 Claude에게 이 설정이 맞는지 물었다. 안 막았으면 더 잘됐을 것 같았다.
어떻게 시켰나
Claude의 첫 답은 “지금 기준으로는 잘못된 설정”이었다. 근거를 날짜로 짚었다.
- 9월 4일에 분류 칩 주소(
?cat=)를 막았다. 당시 웹이 Cloudflare Workers에 있었는데, 요청당 CPU 10ms 제한에 걸려 요청의 19.4%가 죽고 있었다. - 다음 날 웹을 Railway로 옮기면서 그 제한이 사라졌다. 차단 규칙만 16일째 남아 있었다.
차단의 두 번째 근거는 “칩으로 닿는 공시는 어차피 사이트맵에 다 있다”였다. 이것도 실측으로 깨졌다. 사이트맵 목록 492개 중 구글이 받아 간 건 3개뿐이었고, 공시 26만 건이 든 날짜별 파일 490개는 한 번도 다운로드되지 않았다. 사이트맵에 들어 있다고 해서 발견되는 건 아니었다.
잃고 있던 양도 셌다. 공시 상세에는 다른 공시로 가는 링크가 없다. 그래서 칩을 막으면 크롤러가 하루에 닿는 공시는 홈 첫 장의 20건이 전부다. 칩까지 열면 136건이 된다. 차단을 풀었다. 칩 페이지는 대표 주소(canonical)가 홈이라, 풀어도 색인이 중복되지는 않는다.
어디서 막혔나
다음은 서치 콘솔이었다. 날짜별 사이트맵 하나를 제출했더니 상태가 “가져올 수 없음”으로 떴다. 나는 파일을 못 찾았다는 뜻으로 읽었다. Claude가 API로 직접 조회해 보니 isPending: true였고, 마지막 다운로드 기록은 아예 없었다. 실패한 게 아니라 아직 안 읽은 것이다. 화면의 문구만 보고는 이 둘이 구분되지 않는다.
이어서 “서치 콘솔 이슈를 API로 조회해서 해결해 줘”라고 시켰다. 그런데 서치 콘솔 API에는 색인 커버리지나 이슈 목록을 주는 엔드포인트가 없다. 메서드가 11개뿐이다. 그래서 Claude가 URL 검사로 표본 24개를 떠서 이슈 분포를 다시 만들었다.
- 공시 상세 9건: 9건 전부 “Google에 알려지지 않은 URL”
- 종목 페이지: “발견됨 - 현재 색인이 생성되지 않음”
종목 페이지 2,684개가 든 사이트맵은 구글이 매일 받아 간다. 그런데도 그 안의 페이지를 18일째 하나도 가져가지 않았다. 알고도 안 가져간 것이다.
그 판단의 근거로 보이는 숫자가 있었다. 페이지마다 다른 고유 텍스트가 270자 정도다. 요약은 중앙값이 43자였고, 90.8%가 100자 미만이었다. 같은 틀에 270자만 다른 페이지가 26만 개 있는 셈이다.
진행이 너무 더뎌서 답답했다. Claude는 GA 숫자를 꺼냈다. 4주 동안 주간 세션은 59에서 187로 늘었고, 그중 AI 어시스턴트 유입이 25에서 100이 됐다. 검색 유입만 3 → 5 → 6 → 7로 제자리였다. 서비스가 멈춘 게 아니라 검색 쪽만 멈춘 것이다.
어떻게 풀었나
페이지를 두껍게 하기로 했다. Claude가 시안을 HTML로 만들었는데, 표가 기록처럼만 보였다. 나는 지금 공시 설명을 앞에 두고, 이전 공시의 흐름은 그 아래 붙여 달라고 했다. LLM을 더 써야 하냐고도 물었다. 흐름·주가·정정 이력은 DB 조회만으로 되고, 금액 형식도 파서 하나로 충분했다.
요약 프롬프트도 늘렸다. 핵심 포인트는 3개에서 5~6개로, “왜 중요한가”는 한두 문장에서 서너 문장으로 바꿨다. 목록 한 줄에 쓰이는 요약 문장은 그대로 뒀다. 이건 요약 모델을 바꾸면서 전체를 다시 만드는 작업에 같이 실었다.
다음 날 화면을 보니 달라진 게 없었다. 물어보니 Claude는 프롬프트만 바꾸고 화면은 안 바꿨다고 했다. 그런데 실제 페이지를 재 보니 시안의 블록은 이미 화면에 다 있었다. 시안이 있는 걸 다시 그린 것이다.
진짜 차이는 흐름 카드 하나였다. 흐름이 붙은 공시는 1,500자가 넘었고, 안 붙은 공시는 800자 안팎이었다. 흐름 카드는 공시의 76%에 안 붙고 있었다. 화면이 알림 묶음용 분류값을 “흐름을 보여 줄 공시인가”를 판정하는 데 다시 쓰고 있었기 때문이다. 알림 대상이 아닌 정기보고서까지 같이 막혀 있었다. 정기보고서는 분기·반기·사업보고서를 같은 회사끼리 늘어놓는 것만으로 실적 추이가 되는데도 그랬다.
판정을 공시 유형 기준으로 바꿨다. 정기보고서 22,710건 중 88.2%에 흐름 카드가 생긴다. 흐름이 의미 없는 ‘기타’ 유형만 계속 막았다.
색인이 실제로 늘었는지는 아직 모른다. 서치 콘솔은 며칠 뒤에나 움직인다.
배운 점
- 차단 규칙에는 근거의 유효기간이 있다. 이유가 사라져도 규칙은 남는다. robots.txt 옆에 “왜 막았나”를 적어 두면 나중에 다시 따져 볼 수 있다.
- 사이트맵에 들어 있는 것과 발견되는 것은 다르다. 서치 콘솔에서 파일별 마지막 다운로드 시각을 본다. 안 읽힌 사이트맵은 없는 것과 같다.
- “가져올 수 없음”은 실패가 아닐 수 있다. API의
isPending과lastDownloaded로 가린다. - 서치 콘솔 API로는 이슈 목록을 못 받는다. URL 검사 표본으로 분포를 다시 만드는 게 현실적인 방법이다.
- 시안을 그리기 전에 지금 화면을 먼저 잰다. 렌더된 페이지의 글자 수만 비교해도, 무엇이 빠졌는지가 블록 하나 단위로 나온다.