네이버 서치어드바이저 등록과 IndexNow 자동 색인 — 막히는 함정 셋과 해결 코드
네이버 서치어드바이저 등록은 3단계로 끝납니다. 사이트 주소 등록 → 소유 확인 → 사이트맵 제출입니다. 아래에 화면 순서대로 적었습니다.
여기까지는 막힐 게 없습니다. 문제는 그다음, 글을 올릴 때마다 색인 요청이 자동으로 나가게 만드는 부분입니다. 직접 붙이면 함정이 셋 있고, 셋 다 "성공했다고 화면에 뜨는데 실제로는 안 들어가는" 형태라 찾기가 어렵습니다. 저는 이 셋을 앞서 운영하던 사이트에서 먼저 겪었고, 이 사이트에는 미리 반영해서 한 번에 통과했습니다.
등록만 필요하시면 첫 단락만, 자동화까지 하시면 끝까지 보시면 됩니다.
네이버 서치어드바이저 등록 — 3단계
searchadvisor.naver.com 에 네이버 계정으로 들어가 웹마스터도구를 엽니다.
1. 사이트 등록 — 사이트 주소를 넣습니다. https:// 까지 정확히 적습니다. http 와 https, www 유무는 각각 다른 사이트로 취급되니 실제로 열리는 주소 하나로 통일합니다.
2. 소유 확인 — 둘 중 하나를 고릅니다.
- HTML 파일 업로드 — 주는 파일을 사이트 최상단에 그대로 올립니다
- 메타태그 —
<head>안에 한 줄 넣습니다
<meta name="naver-site-verification" content="발급받은_문자열" />
정적 사이트를 쓰신다면 메타태그 쪽이 편합니다. 빌드 템플릿의 <head> 에 한 번 넣어두면 모든 페이지에 자동으로 들어갑니다.
3. 사이트맵·robots 제출 — 확인이 끝나면 요청 → 사이트맵 제출 에 사이트맵 주소를 넣습니다. robots.txt 에도 사이트맵 위치를 적어둡니다.
User-agent: *
Allow: /
Sitemap: https://내주소/sitemap.xml
IndexNow로 자동 색인 요청 붙이기
IndexNow는 "이 주소가 바뀌었으니 와서 봐라"를 검색엔진에 알리는 규약입니다. 네이버가 이걸 지원합니다. 서치어드바이저에 등록하지 않아도 키만 있으면 동작합니다.
준비물은 셋입니다.
| 준비물 | 내용 |
|---|---|
| 키 | 8~128자. 영문·숫자·하이픈만 씁니다. 값 자체는 아무거나 정해도 됩니다 |
| 키 파일 | https://내주소/<키>.txt 로 열려야 하고, 내용도 그 키 |
| 보낼 목록 | 새로 생겼거나 날짜가 바뀐 주소만 |
보내는 형식입니다.
{
"host": "내주소",
"key": "발급한_키",
"keyLocation": "https://내주소/발급한_키.txt",
"urlList": ["https://내주소/글1/", "https://내주소/글2/"]
}
받는 곳은 둘입니다. 네이버 전용(searchadvisor.naver.com/indexnow)과 공용(api.indexnow.org)입니다. 같은 본문을 양쪽에 각각 POST 하면 됩니다.

함정 셋 — 증상, 원인, 해결
하나. 통보 이력을 받는 곳마다 따로 세지 않으면 네이버가 영영 못 받습니다
증상 — 로그에는 "통보 완료"가 찍히는데 네이버에는 아무것도 안 들어갑니다.
원인 — 두 곳에 보내놓고 이력은 한 덩어리로 기록하면, 한쪽만 성공해도 그 주소가 완료로 적힙니다.
| 보낸 곳 | 응답 |
|---|---|
| 공용 엔드포인트 | HTTP 202 접수됨 |
| 네이버 | HTTP 403 거부 |
| 합쳐서 기록한 이력 | 완료 ← 한쪽만 성공해도 완료 |
한 번 완료로 적히면 다음 배포부터는 안 보냅니다. 이미 보냈다고 판단하기 때문입니다. 그 주소는 네이버가 영영 못 받습니다.
해결 — 이력을 엔드포인트별로 나눠 저장합니다. 자료구조 한 겹만 바꾸면 됩니다.
# 이렇게 두면 한쪽 실패가 가려진다
state = {"https://내주소/글1/": "2026-08-07"}
# 받는 곳마다 따로 센다
state = {
"searchadvisor.naver.com": {"https://내주소/글1/": "2026-08-07"},
"api.indexnow.org": {"https://내주소/글1/": "2026-08-07"},
}
def to_send(urls, endpoint, state):
"""이 엔드포인트가 아직 못 받은 주소만 고른다."""
sent = state.get(endpoint, {})
return [u for u, mod in urls if sent.get(u) != mod]
여기에 원칙 하나를 같이 두면 좋습니다. 실패한 주소는 이력에 적지 않습니다. 적지 않으면 다음 배포에서 저절로 다시 시도됩니다. 재시도 로직을 따로 만들 필요가 없습니다.

둘. 키 파일이 아직 안 올라간 상태로 보내면 거부됩니다
증상 — 어떤 날은 되고 어떤 날은 거부됩니다. 코드는 그대로인데 결과가 들쭉날쭉합니다.
원인 — 검색엔진은 통보를 받으면 keyLocation 주소를 가지러 옵니다. 그때 파일이 없으면 거부합니다. 배포가 끝났다는 신호와, 그 파일이 실제로 열리는 시점은 같지 않습니다. 요즘 호스팅은 전 세계 서버에 나눠 퍼뜨리는 구조라 몇 초에서 몇십 초 차이가 납니다.
해결 — 보내기 전에 키 파일을 직접 열어 200이 나오는지 확인합니다.
def key_file_ready(key_url, tries=10, wait=6):
"""키 파일이 실제로 열릴 때까지 기다린다. 안 열리면 이번 배포는 통보를 건너뛴다."""
for _ in range(tries):
req = urllib.request.Request(key_url, headers={"User-Agent": USER_AGENT})
try:
with urllib.request.urlopen(req, timeout=10) as r:
if r.status == 200:
return True
except Exception:
pass
time.sleep(wait)
return False
확인이 실패하면 그 배포는 통보를 건너뜁니다. 이력에 안 적었으니 다음 배포에서 다시 나갑니다. 색인 통보는 부가 기능이라, 실패해도 배포 자체는 성공으로 두는 편이 운영이 단순합니다.
셋. Cloudflare가 파이썬 기본 User-Agent를 막습니다
증상 — 코드가 맞는데 키 파일 확인부터 계속 403입니다. 브라우저로 열면 잘 열립니다.
원인 — User-Agent(요청에 붙는 프로그램 이름표) 입니다. 파이썬 표준 라이브러리를 그대로 쓰면 Python-urllib/3.12 라고 찍히는데, Cloudflare가 이걸 자동 프로그램으로 보고 막습니다. 내 사이트인데 내 코드가 못 들어갑니다.
해결 — 이름표를 명시합니다. 한 줄입니다.
# 기본 User-Agent → HTTP 403
curl -H "User-Agent: Python-urllib/3.12" https://내주소/키.txt
# 이름표를 명시 → HTTP 200
curl -A "my-indexnow-bot/1.0" https://내주소/키.txt
같은 파일인데 이름표 하나로 갈립니다. 키 파일 확인할 때와 통보를 POST 할 때 양쪽 다 붙여야 합니다. 한쪽만 붙이면 증상이 반만 사라져서 원인을 더 못 찾습니다.

덤 — 네이버는 대문 주소 하나만 담긴 요청을 422 Invalid urls 로 거부합니다. 그런데 글 주소들과 섞어 보내면 받습니다. 이유는 확인하지 못했습니다. 대문만 바뀐 배포에서는 통보를 건너뛰는 쪽이 안전합니다.
구글은 자동 색인 요청이 없습니다 — 대신 할 수 있는 것
먼저 결론입니다. 구글에는 일반 글을 색인 요청할 자동화 방법이 없습니다. 찾는 데 시간을 쓰지 않으셔도 됩니다.
| 방법 | 상태 |
|---|---|
| Indexing API | 채용공고(JobPosting)와 방송 일정(BroadcastEvent)만 받습니다. 블로그 글은 대상이 아닙니다 |
| 사이트맵 ping 주소 | 폐기됐습니다. 지금 호출하면 HTTP 404 가 돌아옵니다. 직접 확인했습니다 |
| IndexNow | 구글은 도입하지 않았습니다. 이 글을 쓰는 시점 기준이고, 바뀌면 다시 적겠습니다 |
그래서 구글 쪽은 재크롤을 유도하는 것이 할 수 있는 전부입니다. 대신 이건 제대로 하면 효과가 있습니다.
사이트맵 lastmod를 정확하게 관리하기
구글은 사이트맵의 lastmod 를 재방문 판단에 씁니다. 다만 믿을 수 있을 때만 씁니다.
<url>
<loc>https://내주소/글1/</loc>
<lastmod>2026-08-07</lastmod>
</url>
원칙은 둘입니다.
- 본문이 실제로 바뀐 글만 날짜를 올립니다. 빌드할 때마다 전체를 오늘 날짜로 찍으면, 구글이
lastmod를 무시하기 시작합니다. 한 번 신뢰를 잃으면 되돌리기 어렵습니다. - 오타 수정 같은 사소한 변경에는 올리지 않습니다. 원고 파일의 수정 시각을 그대로 쓰지 말고, 본문 해시가 바뀐 경우에만 갱신하는 편이 안전합니다.
서치콘솔 수동 요청은 언제 쓰나
URL 검사 → 색인 생성 요청은 사람이 눌러야 합니다. 하루에 넣을 수 있는 수가 제한되어 있어서 모든 글에 쓰는 용도가 아닙니다.
- 새로 만든 사이트의 대문과 대표 글 몇 개
- 내용을 크게 고쳐서 다시 평가받고 싶은 글
- 사이트맵에는 있는데 몇 주가 지나도 안 잡히는 글
이 외에는 사이트맵에 맡기고 기다리는 쪽이 낫습니다.
사이트맵을 아예 안 가져갈 때
제출은 됐는데 상태가 계속 보류 중 이고 며칠이 지나도 안 읽어가는 경우가 있습니다. 이럴 때는 기술 결함부터 순서대로 지웁니다.
| 확인할 것 | 판단 기준 |
|---|---|
robots.txt |
크롤러를 막고 있지 않은지. Disallow: / 가 남아 있는 사고가 흔합니다 |
| 사이트맵 안의 주소 | 전부 200 인지. 301·404 가 섞이면 신뢰가 떨어집니다 |
noindex 태그 |
템플릿에 실수로 남아 있지 않은지 |
| canonical | 다른 주소를 가리키고 있지 않은지 |
| 사이트맵 형식 | lastmod 날짜 형식, 주소가 절대경로인지 |
저는 위를 전부 확인했는데도 안 가져가는 상황을 겪었습니다. 결함은 없었습니다. 남은 후보는 둘이었는데 아직 구분하지 못했습니다.
- 만든 지 얼마 안 된 사이트라서
- 여러 사람이 나눠 쓰는 무료 서브도메인을 쓰고 있어서
무료 주소는 남이 먼저 쓴 이력이 같은 도메인에 쌓여 있습니다. 이게 영향을 준다는 확증은 갖고 있지 않습니다. 확인하려면 주소를 바꿔 비교해야 하는데, 그건 해보고 따로 적겠습니다. 혹시 같은 조건에서 결과를 보신 분이 있으면 알려주시면 좋겠습니다.
색인이 실제로 됐는지 확인하는 법
통보가 나갔다고 색인된 것이 아닙니다. 받는 쪽에서 확인해야 합니다.
| 확인 | 방법 |
|---|---|
| 네이버 | 웹마스터도구 → 수집 현황. 검색창에 site:내주소 도 같이 봅니다 |
| 구글 | 서치콘솔 → 색인 생성 → 페이지. 상태별로 몇 건인지 나옵니다 |
| 빠른 확인 | 검색창에 site:내주소/글1/ — 나오면 색인된 것입니다 |
자동화를 만들 때 가장 중요한 원칙이 이겁니다. 내 로그의 "성공"을 믿지 않습니다. 저는 화면에 성공이 뜨는 동안 네이버가 아무것도 못 받고 있었습니다. 보내는 쪽 기록과 받는 쪽 상태를 주기적으로 대조하는 편이 낫습니다.
흔한 오해 셋
| 이렇게 알기 쉽다 | 실제 |
|---|---|
| 네이버가 되니 구글도 되겠지 | 구글은 일반 글에 자동 요청 방법이 없습니다 |
| 알리면 색인되겠지 | 알리는 것과 색인되는 것은 다른 일입니다 |
| 성공이라고 뜨면 성공이겠지 | 한쪽만 성공해도 성공으로 적힐 수 있습니다 |
가운데가 제일 큽니다. 색인 요청은 넣으면 처리되는 신청서가 아니라, 와서 봐달라는 부탁에 가깝습니다. 올지 말지는 검색엔진이 정합니다.
판정 — 조건부로 쓸만
네이버 쪽은 붙일 값어치가 있습니다. 손으로 요청을 넣는 일이 없어졌고, 글을 올리면 알아서 나갑니다. 위 함정 셋을 미리 알고 붙이면 반나절이면 됩니다.
구글 쪽은 붙일 것이 없습니다. 사이트맵 lastmod 관리와 서치콘솔 수동 요청이 전부입니다.
색인이 보장되지도 않습니다. 자동 통보는 "빨리 봐달라"까지고, 실제로 잡히느냐는 사이트 자체의 문제입니다. 저는 지금도 구글에서는 거의 안 잡히고 있습니다.
직접 붙이실 분께
하나. 워드프레스를 쓰신다면 플러그인이 있어서 위 셋을 안 겪습니다. 직접 붙일 때만 해당됩니다.
둘. 색인 요청은 순위와 상관없습니다. 검색 결과에 존재하게 만드는 것까지입니다. 색인은 됐는데 안 보이는 건 다른 문제이고, 그건 본문이 할 일입니다.
셋. 붙이는 순서는 이게 안전합니다. 키 파일 올리기 → curl 로 200 확인 → 주소 한 개로 수동 통보 → 응답 코드 확인 → 그다음에 자동화에 넣기. 자동화부터 만들면 어디서 막혔는지 구분이 안 됩니다.
다음에는 주소를 바꿔서 무료 서브도메인이 색인에 영향을 주는지 비교해보려고 합니다. 결과가 나오면 이 글에 이어서 적겠습니다.