robots.txt는 사이트 루트에 두는 텍스트 파일로, 검색로봇에게 어떤 URL을 수집해도 되는지 알려 줍니다. 1994년에 시작된 관례였지만 2022년 9월 IETF 표준 RFC 9309가 되었고, 네이버 서치어드바이저의 robots.txt 가이드도 이 표준을 근거로 듭니다. 문법은 단순하지만 실수가 잦은 지점이 세 군데 있습니다. 로봇은 그룹 하나만 따르고, 줄 순서가 아니라 더 긴 규칙이 이기며, 파일을 못 받아 오는 경우의 처리가 응답 코드마다 다릅니다.
이 글의 예제 파일은 모두 2026-10-02에 두 가지 파서로 판정했습니다. Scrapy가 기본으로 쓰는 Protego 0.7.0과 Python 3.12의 urllib.robotparser입니다. 두 결과가 다를 때 RFC와 구글 문서에 맞는 쪽은 Protego입니다. CPython은 Python 3.13.14와 3.14.5에서 이 모듈을 RFC 9309에 맞게 다시 작성했으므로(gh-138907), 2026-10-03에 Python 3.14.7로도 같은 파일을 판정하고 결과가 달라지는 곳을 함께 적었습니다. 네이버의 판정 엔진은 공개되어 있지 않으므로, 네이버 쪽 동작은 서치어드바이저 문서에 적힌 범위에서만 다룹니다.
파일 위치와 네이버 검색로봇의 기본 동작
검색로봇은 호스트 바로 아래의 소문자 /robots.txt만 요청합니다(RFC 9309 2.3절). 규칙은 같은 프로토콜, 호스트, 포트에만 적용됩니다. 서치어드바이저 가이드의 예시처럼 http://www.example.com/robots.txt의 내용은 http://example.com/과 https://example.com/에는 적용되지 않습니다. www가 붙은 주소와 붙지 않은 주소를 모두 운영한다면 각각에 파일이 필요합니다.
네이버 검색로봇의 이름은 Yeti입니다. 서치어드바이저는 루트에 robots.txt가 없으면 모든 콘텐츠를 수집할 수 있다고 간주한다고 밝히고, 파일은 텍스트(text/plain)로 접근 가능해야 한다고 적고 있습니다. 또 웹마스터와 별도 협약이 있는 경우나 광고주 정보 확인, 링크 미리보기 생성처럼 특수한 용도의 로봇은 robots.txt를 참조하지 않거나 완전히 준수하지 않을 수 있다고 밝힙니다. 개인 정보가 담긴 페이지는 로그인 같은 다른 방법으로 보호해야 한다는 뜻입니다. RFC 9309의 3절도 robots.txt는 접근 제어가 아니며, 파일에 경로를 적으면 오히려 그 경로가 공개된다고 경고합니다.
수집을 막는 것과 검색 노출을 막는 것도 다릅니다. 구글은 차단된 URL이라도 다른 페이지에서 링크되면 스니펫 없이 색인할 수 있다고 설명합니다(Google의 robots.txt 사양 해석). 검색 결과에서 빼려면 수집을 허용한 상태에서 noindex를 보내야 합니다. 서치어드바이저도 noindex가 표기된 페이지는 검색 반영에서 제외한다고 안내합니다.
로봇은 그룹 하나만 따른다
그룹은 하나 이상의 User-agent 줄과 그 뒤의 규칙 묶음입니다. 로봇은 자기 이름과 일치하는 그룹을 찾으면 그 그룹만 따르고, 이름이 일치하는 그룹이 없을 때만 * 그룹을 씁니다(RFC 9309 2.2.1절). 같은 이름의 그룹이 여러 개면 하나로 합쳐지지만, * 그룹과 이름 있는 그룹은 합쳐지지 않습니다.
서치어드바이저가 소개하는 “네이버 검색로봇만 수집 허용” 예제가 이 규칙을 이용합니다. ZeroTool 생성기에서 * 블록에 Disallow /, 직접 입력한 Yeti 블록에 Allow /를 넣으면 같은 파일이 나옵니다.
User-agent: *
Disallow: /
User-agent: Yeti
Allow: /
두 파서 모두 Yeti는 전부 허용, Googlebot은 전부 차단으로 판정했습니다. 그런데 같은 규칙 때문에 의도와 반대가 되는 경우도 생깁니다. 장바구니 /cart/를 모든 로봇에게 막아 두고, 네이버에는 내부 검색 결과도 막으려고 Yeti 블록을 추가한 파일입니다.
User-agent: *
Disallow: /cart/
User-agent: Yeti
Disallow: /search/
Yeti는 자기 그룹만 읽기 때문에 /cart/를 수집할 수 있게 됩니다. Yeti 블록에도 Disallow: /cart/를 반복해 적어야 합니다. 빙도 Bingbot 전용 섹션이 있으면 일반 섹션을 무시하니 공통 규칙을 반복하라고 안내합니다(Bing 도움말). 구글은 User-agent, Allow, Disallow 외의 줄(Sitemap 등)은 그룹을 끊지 않는다고 설명하며, 빈 줄에도 구분의 의미는 없습니다.
순서가 아니라 길이: 가장 구체적인 규칙이 이긴다
선택된 그룹 안에서는 URL 경로의 첫 글자부터 일치하는 규칙 가운데 일치한 바이트 수가 가장 많은 규칙이 적용됩니다. 파일 안의 순서는 상관없습니다. 길이가 같은 Allow와 Disallow가 충돌하면 RFC는 Allow를 쓰도록 권고하고(SHOULD), 구글은 “덜 제한적인 규칙”을 씁니다(RFC 9309 2.2.2절). 어떤 규칙과도 일치하지 않으면 허용입니다.
특수 문자는 두 가지입니다. *는 임의의 문자열, $는 URL의 끝을 뜻합니다. 서치어드바이저의 “루트 페이지만 수집 허용” 예제가 $를 씁니다.
User-agent: *
Disallow: /
Allow: /$
| 경로 | RFC 9309 기준으로 적용되는 규칙 | Protego | urllib.robotparser (Python 3.12) | urllib.robotparser (Python 3.14.7) |
|---|---|---|---|---|
/ | Allow: /$가 Disallow: /보다 길다 | 허용 | 차단 | 허용 |
/index.html | $가 맞지 않아 Disallow: / | 차단 | 차단 | 차단 |
/?ref=a | 쿼리가 붙으면 $가 맞지 않음 | 차단 | 차단 | 차단 |
Python 3.12의 urllib.robotparser는 RFC 이전 방식으로 파일 위에서부터 처음 일치한 줄을 쓰고 *와 $를 해석하지 않아서 루트까지 차단으로 판정합니다. Python 3.13.14·3.14.5부터는 가장 긴 규칙과 *·$를 따르며, 3.14.7은 이 표의 세 경로를 모두 Protego와 같게 판정했습니다. 이 모듈로 사이트를 점검하는 스크립트가 있다면 먼저 실행 환경의 Python 버전을 확인하고, 3.12 이하라면 결과를 그대로 믿으면 안 됩니다.
서치어드바이저의 또 다른 예제 Disallow: /private*/도 확인했습니다. /private-image/a.jpg, /private/, /privatevideo/1은 차단되지만 /private.html은 허용됩니다. * 뒤에 /가 있어서 디렉터리 형태의 경로만 걸리기 때문입니다.
회원 영역을 막으면서 가입 페이지 하나만 열어 두는 경우도 길이로 결정됩니다.
User-agent: *
Disallow: /member
Allow: /member/join$
/member/join은 허용되지만, 광고 파라미터가 붙은 /member/join?ref=a는 $ 때문에 차단됩니다. 끝의 슬래시가 없는 Disallow: /member는 접두어 일치라서 /members까지 막습니다. 경로는 대소문자를 구분하므로 /Member는 막히지 않습니다. 한글 경로는 비교 전에 UTF-8 퍼센트 인코딩으로 바뀌므로, 파일은 반드시 UTF-8로 저장해야 합니다.
응답 코드별 처리: RFC·구글·네이버 비교
파일을 정상적으로 받지 못했을 때의 동작은 검색엔진마다 조금씩 다릅니다. 네이버 열은 서치어드바이저 가이드의 “HTTP 응답코드에 따른 처리” 표를 옮긴 것입니다.
/robots.txt 응답 | RFC 9309 | 구글 | 네이버 |
|---|---|---|---|
| 2xx | 해석 가능한 규칙을 따름 | 같음. HTML이 와도 규칙을 추출하려고 시도 | 규칙을 해석. 단, HTML 문서로 반환되면 유효한 규칙이 있어도 “없음(모두 허용)“으로 해석될 수 있음 |
| 3xx | 최소 5번 리디렉션을 따라감 | 5번을 넘으면 404로 처리 | 5회까지 허용, 그 이상이면 중단하고 “모두 허용”. HTML·자바스크립트 리디렉션은 해석하지 않음 |
| 4xx | 모든 리소스 접근 가능(MAY) | 429를 제외한 4xx는 “제한 없음" | "모두 허용” |
| 5xx | 전부 차단으로 간주 | 처음 12시간 수집 중단, 이후 30일간 마지막 정상본 사용 | ”모두 허용하지 않음”. 이전에 정상 수집한 규칙이 있으면 일시적으로 사용 |
| 크기 | 최소 500KiB까지 해석 | 500KiB 이후는 무시 | 문서에 명시 없음 |
차이가 큰 곳은 2xx의 HTML 처리입니다. 단일 페이지 앱이나 일부 호스팅은 없는 경로에 200 상태로 index.html을 돌려줍니다. robots.txt를 올리지 않은 채 이런 설정이면, 구글은 HTML에서 규칙을 찾으려 하고 네이버는 “모두 허용”으로 볼 수 있습니다. 어느 쪽이든 의도한 규칙은 적용되지 않으니 실제 텍스트 파일을 두는 편이 확실합니다. 또 방화벽이 로봇의 /robots.txt 요청에 403을 돌려주면 세 기준 모두 “제한 없음”이 되고, 점검 중에 503을 돌려주면 구글과 네이버 모두 수집을 멈춥니다. 서치어드바이저가 IP 기반 차단 대신 robots.txt를 권하는 이유도 여기에 있습니다.
AI 크롤러 토큰과 검색 노출
AI 회사들은 학습용, 자체 검색용, 사용자 요청에 따른 접근용으로 토큰을 나누어 공개하고 있습니다. 하나를 막아도 나머지는 그대로입니다.
| 토큰 | 운영사 | 차단했을 때의 의미(각 사 공식 문서) |
|---|---|---|
GPTBot | OpenAI | 학습에 사용하지 말라는 신호(OpenAI 크롤러) |
OAI-SearchBot | OpenAI | ChatGPT 검색 답변에 표시되지 않음(내비게이션 링크 제외) |
ClaudeBot, Claude-SearchBot, Claude-User | Anthropic | 학습, 검색 색인, 사용자 요청 접근. 세 가지 모두 robots.txt를 따름(Anthropic 도움말) |
Google-Extended | Gemini 학습과 그라운딩. 구글 검색 노출과 순위에는 영향 없음(Google 일반 크롤러) | |
PerplexityBot | Perplexity | Perplexity 검색 결과. 사용자 요청용 Perplexity-User는 대체로 robots.txt를 무시(Perplexity Crawlers) |
CCBot | Common Crawl | 공개 크롤 데이터. 학습 데이터 출처로 많이 쓰임(CCBot) |
Google-Extended는 별도의 User-Agent 문자열이 없는 제어용 토큰이라 접속 로그에 나타나지 않습니다. 학습만 막고 AI 검색 노출은 유지하려면 GPTBot, ClaudeBot, Google-Extended, CCBot처럼 학습용 토큰만 차단하고, 검색용 토큰은 그대로 두면 됩니다. robots.txt는 요청일 뿐이라 따르지 않는 로봇은 서버나 CDN에서 막아야 합니다.
검증 도구와 ZeroTool 생성기 사용 시 주의점
네이버 웹마스터도구의 robots.txt 도구는 두 가지 기능을 제공합니다. 루트의 robots.txt를 고친 뒤 “수집 요청”으로 검색로봇에 바로 알리고, 설정된 규칙으로 특정 페이지의 수집 가능 여부를 테스트할 수 있습니다. 간단 생성 기능도 있습니다. 구글 서치 콘솔의 robots.txt 보고서(설정 → robots.txt)는 속성의 상위 20개 호스트에 대해 구글이 가져온 파일과 시각, 해석하지 못한 줄을 보여 주고 재크롤링 요청을 받습니다. URL 하나의 판정은 URL 검사 도구를 씁니다. 예전의 robots.txt 테스터는 2023년에 종료되었습니다.
로컬에서는 RFC에 맞는 파서로 확인할 수 있습니다.
from protego import Protego
import urllib.request
body = urllib.request.urlopen("https://example.co.kr/robots.txt").read().decode("utf-8")
rp = Protego.parse(body)
for path in ["/", "/member/join", "/cart/"]:
print(path, rp.can_fetch("https://example.co.kr" + path, "Yeti"))
robots.txt 생성기에서는 블록마다 *, Googlebot, Bingbot 중 하나를 고르거나 “직접 입력”으로 Yeti 같은 토큰을 넣고, 허용·차단 줄과 사이트맵 URL을 추가합니다. 이 글의 파일 예제는 모두 이 도구로 만들었고 테스트에서 도구 코드와 대조합니다. 몇 가지 동작을 알아 두면 좋습니다.
- 처음 열면
User-agent: *와Disallow: /가 들어 있어 사이트 전체가 차단됩니다. 스테이징 서버라면 맞지만 운영 서버에 올리기 전에는 반드시 바꾸세요. - 규칙이 없는 블록은 빈
Disallow:로 출력되며, 해당 로봇에게 모두 허용이라는 뜻입니다. - 블록 하나에 User-agent는 하나입니다. 경로는 입력한 그대로 출력되며
/로 시작하는지, 와일드카드가 의도대로인지는 검사하지 않습니다. - 사이트맵은 파일 끝에 한 줄만 씁니다. 서치어드바이저 예제처럼 사이트맵 위치를 robots.txt에 적어 두면 수집에 도움이 됩니다.
검색 결과에서 빼야 하는 페이지는 robots.txt 대신 메타 태그 생성기로 noindex를 넣으세요.