main-logo

검색엔진은 우리 사이트를 어떻게 발견할까?

프론트엔드 개발자가 알아야 할 SEO/GEO 두 번째 이야기, 크롤러가 닿지 못하면 콘텐츠도 없다

profile
shushushu
2026년 04월 14일 · 0 분 소요

들어가며

지난 편에서 프론트엔드 개발자가 왜 SEO를 챙겨야 하는지, 그리고 GEO라는 새로운 관점이 왜 필요해졌는지 이야기했어요. 이번 편에서는 좀 더 실전적인 이야기를 해볼게요.

검색엔진이 우리 사이트를 검색 결과에 보여주려면, 먼저 우리 사이트를 발견해야 하잖아요. 근데 이 "발견"이라는 과정이 생각보다 단순하지 않더라고요. SEO/GEO 분석 서비스를 만들면서 수많은 사이트를 들여다봤는데, 콘텐츠는 멀쩡한데 크롤러가 아예 접근을 못 하는 경우가 의외로 많았어요. 대기업 사이트에서도요.

이번 편에서는 검색엔진 크롤러가 우리 사이트를 발견하고 색인하는 과정을 프론트엔드 개발자 관점에서 풀어볼게요.


크롤링 → 인덱싱 → 랭킹, 이 흐름부터 잡자

검색엔진이 검색 결과를 보여주기까지는 크게 세 단계를 거쳐요.

크롤링(Crawling) — 크롤러가 웹을 돌아다니면서 페이지를 발견하고 수집하는 단계예요. 이때 크롤러는 링크를 따라가거나 sitemap을 참고해서 페이지를 찾아요.

인덱싱(Indexing) — 수집한 페이지의 내용을 분석해서 데이터베이스에 저장하는 단계예요. 페이지 제목이 뭔지, 어떤 주제인지, 어떤 키워드가 포함됐는지 등을 파악해서 정리해요.

랭킹(Ranking) — 사용자가 검색했을 때, 인덱스에 저장된 페이지들 중에서 가장 적합한 걸 골라서 순서대로 보여주는 단계예요.

여기서 핵심은, 크롤링이 안 되면 인덱싱도 안 되고, 인덱싱이 안 되면 랭킹에 아예 참여할 수 없다는 거예요. 아무리 좋은 콘텐츠를 만들어도 크롤러가 접근할 수 없으면 검색 결과에 나타나지 않아요. 그래서 기술적 SEO의 출발점은 항상 "크롤러가 우리 사이트에 제대로 접근할 수 있는가"예요.


robots.txt — 크롤러에게 보내는 첫 번째 신호

크롤러가 어떤 사이트를 방문하면 가장 먼저 확인하는 파일이 robots.txt예요. 사이트 루트에 위치하는 텍스트 파일인데, "이 사이트에서 어디를 탐색해도 되고, 어디는 안 되는지"를 크롤러에게 알려주는 역할이에요.

# 기본적인 robots.txt 예시

User-agent: * Allow: / Disallow: /admin/ Disallow: /api/ Sitemap: https://example.com/sitemap.xml

간단해 보이지만, 이 파일 하나가 SEO에 미치는 영향이 꽤 커요.

robots.txt가 없거나 잘못 설정된 경우

실제로 분석하다 보면 이런 케이스를 자주 만나요.

robots.txt 자체가 없는 경우 — 파일이 없더라도 크롤러는 일반적으로 모든 페이지에 접근 가능한 상태로 해석해요. 그래서 즉시 치명적인 문제가 생기지는 않을 수 있어요. 다만 robots.txt를 두면 sitemap 위치를 명시적으로 안내할 수 있고, 검색엔진 크롤러별 탐색 정책을 세밀하게 제어할 수 있어요. 특히 운영 환경에서는 관리 페이지나 불필요한 API 경로에 대한 크롤링을 제한하는 용도로 활용하는 경우가 많아요. 분석해본 사이트 중 꽤 많은 경우가 "파일 자체를 몰랐거나, 초기에 깜빡하고 그냥 운영 들어간" 경우였어요.

Disallow: /로 전체 차단한 경우 — 이건 진짜 치명적이에요. 모든 검색엔진 크롤러를 사이트 전체에서 차단하겠다는 의미예요. 실제로 이런 설정이 된 사이트가 있었는데, 검색 결과에서 완전히 사라져 있더라고요. 개발 환경에서 설정해둔 걸 운영에 그대로 올린 거였어요. 결과적으로 멀쩡한 사이트가 몇 달 동안 검색 노출이 0이었던 케이스예요.

핵심 디렉터리를 차단한 경우/product//service/ 같은 중요한 경로를 Disallow에 넣어버리면, 정작 사용자에게 보여줘야 할 페이지가 검색 결과에서 빠져요. CMS 관련 경로를 막으려다가 실수로 전체 콘텐츠 경로를 막는 경우가 종종 있어요.

프론트엔드 개발자가 챙겨야 할 포인트

Next.js나 Nuxt 같은 프레임워크를 쓰고 있다면 robots.txt를 직접 관리해야 해요. Next.js의 경우 app/robots.ts에서 동적으로 생성할 수도 있고, public/robots.txt에 정적 파일로 놓을 수도 있어요.

// Next.js app/robots.ts 예시
import { MetadataRoute } from 'next' export default function robots(): MetadataRoute.Robots { return { rules: { userAgent: '*', allow: '/', disallow: ['/admin/', '/api/', '/private/'], }, sitemap: 'https://example.com/sitemap.xml', } }

중요한 건, 배포할 때 https://내도메인/robots.txt에 직접 접속해서 200 응답이 오는지, 내용이 의도한 대로 나오는지 눈으로 확인하는 거예요. 빌드 과정에서 빠지거나, 서버 설정에 따라 404가 뜨는 경우가 은근히 있거든요. 특히 배포 파이프라인 바꾼 직후에 한 번씩 꼭 확인하는 게 좋아요.


Sitemap — 사이트의 전체 지도를 건네주기

robots.txt가 "어디를 탐색해도 되는지"를 알려준다면, sitemap은 "우리 사이트에 어떤 페이지들이 있는지"를 목록으로 알려주는 역할이에요.

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url>
    <loc>https://example.com/</loc>
    <lastmod>2026-03-15</lastmod>
  </url>
  <url>
    <loc>https://example.com/products</loc>
    <lastmod>2026-03-20</lastmod>
  </url>
</urlset>

크롤러는 링크를 따라가면서 페이지를 발견하기도 하지만, 사이트 규모가 커지면 링크만으로는 모든 페이지를 찾기 어려워요. sitemap이 있으면 크롤러가 사이트 전체 구조를 한눈에 파악할 수 있어서 크롤링 효율이 올라가요.

sitemap 관련 흔한 실수들

robots.txt에 sitemap 경로를 안 적은 경우 — sitemap 파일을 만들어놔도 robots.txt에서 경로를 알려주지 않으면 크롤러가 찾기 어려워요. Google Search Console에서 수동으로 제출할 수도 있지만, robots.txt에 한 줄 추가하는 게 가장 확실해요.

sitemap URL이 깨진 경우 — sitemap에 등록된 URL이 실제로 404나 500을 반환하면 크롤러 입장에서 사이트 품질이 낮아 보여요. 특히 콘텐츠를 삭제하거나 URL 구조를 바꿀 때 sitemap을 업데이트하는 걸 빠뜨리는 경우가 많아요. sitemap에 있는 URL은 200 응답이 오는 유효한 페이지여야 해요.

lastmod 날짜가 의미 없는 경우 — 모든 URL의 lastmod를 오늘 날짜로 일괄 설정해두는 사이트를 꽤 봤어요. 배포 스크립트에서 현재 날짜로 자동 채워지게 해둔 경우인데, 이러면 크롤러가 "어떤 페이지가 실제로 업데이트됐는지" 판단할 수 없어요. 실제 콘텐츠 수정 날짜를 넣는 게 중요해요.

대규모 사이트는 sitemap index를 쓰자

sitemap 하나에는 URL 50,000개까지만 넣을 수 있어요. 그 이상이면 sitemap을 여러 개로 나누고, sitemap index 파일로 묶어야 해요.

<?xml version="1.0" encoding="UTF-8"?>
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <sitemap>
    <loc>https://example.com/sitemap-posts.xml</loc>
  </sitemap>
  <sitemap>
    <loc>https://example.com/sitemap-products.xml</loc>
  </sitemap>
</sitemapindex>

Next.js에서는 app/sitemap.ts에서 동적으로 생성할 수 있어요. 페이지가 추가되거나 변경될 때 sitemap도 자동으로 갱신되게 만들면 관리 부담이 줄어요.

// Next.js app/sitemap.ts 예시
import { MetadataRoute } from 'next' export default async function sitemap(): Promise<MetadataRoute.Sitemap> { // DB나 CMS에서 동적 페이지 목록을 가져오는 경우 const posts = await fetchPosts() const postEntries = posts.map((post) => ({ url: `https://example.com/posts/${post.slug}`, lastModified: post.updatedAt, })) return [ { url: 'https://example.com', lastModified: new Date('2026-01-15'), // 실제 최종 수정일을 넣어야 해요 }, { url: 'https://example.com/products', lastModified: new Date('2026-03-20'), // 실제 최종 수정일을 넣어야 해요 }, ...postEntries, ] }

여기서 핵심은 lastModified에 실제 콘텐츠 수정 날짜를 넣는 거예요. 정적 페이지도 new Date()처럼 빌드 시점의 현재 날짜를 쓰면, 앞서 얘기한 "모든 URL을 오늘 날짜로 일괄 설정하는 실수"와 똑같은 문제가 생겨요. 동적 페이지처럼 실제 수정일을 명시하는 습관을 들이는 게 좋아요.


내부 링크 — 크롤러가 실제로 페이지를 탐색하는 경로

robots.txt와 sitemap 얘기를 했는데, 사실 크롤러가 새 페이지를 발견하는 가장 기본적인 방식은 링크를 타고 이동하는 것이에요. 이 부분을 빠뜨리면 크롤링 설명이 반쪽짜리가 돼요.

<a href> vs JavaScript 이벤트

검색 크롤러는 일반적으로 HTML의 <a href> 기반 링크를 가장 안정적으로 탐색해요. 반면 JavaScript 이벤트 기반 라우팅은 크롤러 종류와 렌더링 방식에 따라 링크로 인식되지 않거나 우선순위가 낮아질 수 있어요. 그래서 주요 탐색 경로는 가능하면 <a> 또는 프레임워크의 공식 Link 컴포넌트를 사용하는 것이 권장돼요.

SPA에서 라우팅을 처리할 때 이 부분을 놓치기 쉬워요. React Router나 Next.js의 <Link> 컴포넌트는 내부적으로 <a> 태그를 생성하기 때문에 괜찮지만, 커스텀 네비게이션을 만들 때는 확인이 필요해요.

// 크롤러가 안정적으로 따라갈 수 있는 링크
<a href="/products/123">상품 보기</a>
<Link href="/products/123">상품 보기</Link>
// 크롤러에 따라 인식되지 않거나 우선순위가 낮아질 수 있는 링크 <div onClick={() => router.push('/products/123')}>상품 보기</div>

네비게이션과 푸터는 크롤러 입장에서 사이트 전체 구조를 파악하는 중요한 단서이기도 해요. 주요 페이지들이 이 영역에서 링크로 연결돼 있다면 크롤러가 사이트 구조를 더 빠르게 이해할 수 있어요.


크롤 예산 — 크롤러에게도 한계가 있다

robots.txt와 sitemap, 내부 링크로 크롤러를 잘 불러들였다면, 이제는 크롤러가 사이트 안에서 헤매지 않도록 URL 구조를 정리할 차례예요.

"크롤 예산"이라는 말을 처음 들으면 다소 생소할 수 있어요. 간단히 말하면, Googlebot이 특정 사이트에 일정 기간 동안 할당하는 크롤링 자원의 한계예요. 사이트 규모, 서버 응답 속도, 링크 구조 등을 기반으로 결정돼요.

대부분의 소규모 사이트에서는 크롤 예산이 크게 문제가 안 돼요. 근데 페이지 수가 수만 개 이상이거나, URL 구조가 지저분한 경우엔 크롤 예산이 생각보다 빨리 소진돼요.

크롤 예산을 낭비하는 주요 원인들

무한한 URL 생성 — 필터링, 정렬, 검색 파라미터가 URL에 붙는 구조라면 조합이 기하급수적으로 늘어나요. ?sort=price&color=red&size=M 같은 조합이 무한히 생기면, 크롤러가 의미 없는 URL을 탐색하는 데 자원을 써버려요.

# 크롤 예산을 낭비하는 URL 패턴
/products?sort=price&page=1 /products?sort=price&page=2 /products?sort=name&page=1 /products?color=red&sort=price ...

이런 경우에는 우선 rel="canonical"로 원본 URL을 명확히 지정하고, 내부 링크와 sitemap도 표준 URL 기준으로 정리하는 것이 좋아요. 필요하다면 크롤링 부하를 줄이기 위해 일부 파라미터 URL에 대해 robots.txt로 접근을 제한할 수는 있지만, robots.txt는 canonical을 대신하는 수단은 아니에요. Google은 중복 URL 정리에는 canonical을, 크롤링 자체를 막을 때는 robots.txt를 구분해서 사용하도록 안내하고 있어요.

세션 ID가 URL에 포함된 경우?sessionid=abc123 같은 값이 URL에 붙으면, 같은 페이지가 수백만 개의 URL로 인식돼요. 요즘은 세션을 쿠키로 관리하는 게 일반적이지만, 레거시 시스템에서 종종 보여요.


HTTPS와 리다이렉트 — 크롤러가 길을 잃지 않게

HTTP에서 HTTPS로의 리다이렉트

요즘 대부분의 사이트가 HTTPS를 쓰지만, HTTP로 접속했을 때 HTTPS로 제대로 리다이렉트되는지는 별도로 확인해야 해요. http://example.com으로 접속했을 때 https://example.com으로 301 리다이렉트가 돼야 해요.

이게 안 돼 있으면 검색엔진이 HTTP 버전과 HTTPS 버전을 별개의 페이지로 인식할 수 있어요. 같은 콘텐츠가 두 개의 URL에 존재하는 셈이 되니까 검색 노출이 분산돼요.

www vs non-www

비슷한 맥락에서, https://example.comhttps://www.example.com 중 하나로 통일해야 해요. 둘 다 접근 가능한 상태라면 크롤러는 두 개의 다른 사이트로 인식할 수 있거든요. 어느 쪽을 쓸지 결정하고, 나머지는 301로 리다이렉트해두세요.

리다이렉트 체인 문제

A → B → C → D 같은 식으로 리다이렉트가 여러 번 연쇄되는 경우가 있어요. Googlebot은 한 요청당 최대 10번의 리다이렉트 홉까지만 따라가고, 그걸 넘으면 Search Console의 페이지 색인 보고서에 리다이렉트 오류로 기록돼요. 한도 안이라도 홉이 늘어날수록 크롤링 효율이 떨어지고, 다른 크롤러는 더 일찍 포기할 수도 있어서 실무에서는 3~5회 이하로 유지하는 걸 목표로 잡는 게 안전해요. 리다이렉트는 가능하면 한 번에 최종 목적지로 보내는 게 좋아요.

리다이렉트 체인은 URL 구조를 바꿀 때 이전 리다이렉트를 그대로 두고 새 리다이렉트를 추가하는 과정이 반복되면서 생겨요. 주기적으로 점검하는 게 좋아요.

삭제된 페이지는 어떻게 처리할까

페이지를 삭제했을 때 그냥 404로 두는 경우가 많은데, 유사한 콘텐츠로 연결할 수 있다면 301 리다이렉트를 설정하는 게 좋아요. 대체 페이지가 아예 없다면 410(Gone)으로 응답하면 크롤러에게 "이 페이지는 의도적으로 삭제된 거야"라고 명확하게 알려줄 수 있어요. 404와 달리 410은 크롤러가 재방문을 빠르게 포기해서 크롤 예산 낭비를 줄여줘요.


Canonical 태그 — "이게 원본이야"라고 선언하기

프론트엔드 개발을 하다 보면 같은 콘텐츠가 여러 URL에서 접근 가능한 경우가 자주 생겨요.

  • https://example.com/products?sort=price
  • https://example.com/products?sort=price&page=1
  • https://example.com/products

이 세 URL이 사실상 같은 상품 목록을 보여주고 있다면, 검색엔진은 어떤 URL을 검색 결과에 보여줘야 할지 헷갈려해요. canonical 태그는 이 중 하나를 "원본"으로 지정하는 역할이에요.

<link rel="canonical" href="https://example.com/products" />

SPA에서 쿼리 파라미터를 많이 쓰거나, 필터링·정렬 기능이 URL에 반영되는 사이트라면 canonical 태그 관리가 특히 중요해요. 이걸 제대로 안 하면 검색엔진이 같은 페이지를 여러 개로 인식해서 크롤 예산을 낭비하게 돼요.

self-canonical의 중요성

페이지가 하나뿐이더라도 canonical 태그를 자기 자신을 가리키도록 설정하는 걸 권장해요. 이걸 "self-canonical"이라고 하는데, 검색엔진에게 "이 URL이 이 콘텐츠의 정식 주소야"라고 명확히 알려주는 거예요. 외부에서 쿼리 파라미터를 붙여서 링크할 때 생길 수 있는 중복 문제를 예방할 수 있어요.


CSR과 크롤링 — JavaScript 의존도를 점검하자

요즘 React, Vue, Angular 같은 프레임워크로 SPA를 많이 만드는데, CSR(Client-Side Rendering)로만 돌아가는 사이트는 크롤링에서 불리할 수 있어요.

Googlebot은 JavaScript 렌더링을 적극적으로 지원하는 대표적인 검색 크롤러예요. 다만 렌더링에 시간이 걸리고 크롤 예산을 더 많이 소모하기 때문에, CSR에만 의존하면 크롤링 효율이 떨어질 수 있어요. 반면 GPTBot, ClaudeBot, PerplexityBot 등 주요 AI 크롤러는 JavaScript 실행 범위가 제한적이거나 상세 동작이 공개되지 않았어요. Vercel과 MERJ가 한 달간 약 5억 7천만 건의 GPTBot 요청을 분석한 결과, JavaScript 실행 흔적이 전혀 발견되지 않았어요. 같은 분석에서 OAI-SearchBot, ChatGPT-User, ClaudeBot도 모두 JavaScript를 실행하지 않는 것으로 확인됐어요.

핵심 콘텐츠가 JavaScript 실행 없이는 HTML에 아예 존재하지 않는 구조라면, 크롤러가 그 콘텐츠를 인식하지 못할 수 있어요. Next.js의 SSR이나 SSG를 쓰는 이유가 여기에도 있는 거예요.

간단하게 확인하는 방법이 있어요. 브라우저에서 JavaScript를 끄고 우리 사이트에 접속해보는 거예요. 핵심 텍스트 콘텐츠가 보이는지, H1 태그가 있는지, 네비게이션 링크가 <a> 태그로 작동하는지 확인해보세요. 이걸로 크롤러가 보는 화면을 대략적으로 파악할 수 있어요.


설정 다 했으면, 실제로 잘 됐는지 확인하자

설정을 다 했다면, 실제로 크롤러가 우리 사이트를 어떻게 보고 있는지 확인하는 도구가 필요해요.

Google Search Console

Google Search Console(GSC)은 Google 크롤러 관점에서 사이트 상태를 확인할 수 있는 도구예요.

URL 검사 도구 — 특정 URL이 색인됐는지, 색인 안 됐다면 이유가 뭔지 확인할 수 있어요. "URL이 Google에 등록되어 있지 않음"이 뜨면서 "robots.txt에 의해 차단됨"이라고 나온다면, 앞서 말한 robots.txt 문제를 바로 잡아낼 수 있어요.

Sitemap 제출 및 상태 확인 — sitemap을 등록하고 나면 GSC에서 "읽힌 URL 수"가 나와요. 내가 등록한 URL 수와 크게 차이가 난다면 sitemap에 유효하지 않은 URL이 섞여 있거나, 크롤러가 접근 못 하는 페이지가 있다는 신호예요.

페이지 색인 보고서 — 색인된 페이지, 오류가 있는 페이지, 제외된 페이지를 한눈에 볼 수 있어요. (예전 명칭인 '커버리지 리포트'와 동일한 기능이에요.) "제외됨" 항목 중 "중복, Google이 표준 페이지를 선택함"이 많이 뜬다면 canonical 관리가 안 되고 있다는 신호예요.

Bing Webmaster Tools

Google이 GSC를 제공하듯, Bing에도 동일한 역할의 도구가 있어요. Bing Webmaster Tools(webmaster.bing.com)예요.

사이트를 등록하고 sitemap을 제출하면, Bing이 어떤 페이지를 색인했는지, 크롤링 오류는 없는지 확인할 수 있어요. 한국에서는 대부분 Bing은 아예 신경 안 쓰는 경우가 많은데, 뒤에서 다룰 ChatGPT 인용을 원한다면 여기도 한 번은 확인해두는 게 좋아요.

네이버 서치어드바이저

한국 서비스라면 네이버도 빠뜨릴 수 없어요. 네이버 서치어드바이저(searchadvisor.naver.com)는 네이버 검색 크롤러 관점에서 사이트 상태를 확인할 수 있는 도구예요.

GSC와 마찬가지로 sitemap을 등록하고, 크롤링 오류와 색인 상태를 확인할 수 있어요. 국내 B2C 서비스라면 특히 네이버 유입 비중이 높은 경우가 많아서, GSC만큼 주기적으로 들여다보는 게 좋아요.

네이버는 Googlebot과 별도로 Yeti라는 자체 크롤러를 운영해요. User-agent: *에 대해 이미 접근을 허용하고 있다면 별도 설정이 꼭 필요한 건 아니에요. 다만 검색엔진별로 robots.txt를 다르게 운영하고 있다면, Yeti가 의도치 않게 차단되고 있지는 않은지 함께 확인해보는 게 좋아요.

# 검색엔진별로 다르게 운영할 때 Yeti 명시적 허용 예시
User-agent: Yeti Allow: /

새로운 서비스를 배포하거나 URL 구조를 바꾼 직후에는 GSC, Bing Webmaster Tools, 네이버 서치어드바이저를 한 번씩 열어보는 습관을 들이면 좋아요. 크롤러가 사이트를 어떻게 인식하고 있는지 검색엔진별로 직접 피드백을 받을 수 있거든요.


AI 검색 시대, 크롤러 전략도 달라졌다

1편에서 GEO 이야기를 했었는데, 크롤링 단계에서 바로 연결되는 부분이 있어요. 근데 여기서 한 가지 구분을 짚고 넘어가는 게 중요해요. AI와 크롤링의 관계는 사실 두 가지가 섞여 있거든요.

AI 봇은 이제 목적별로 분리되어 있다

최근 OpenAI와 Anthropic 모두 크롤러를 목적별로 분리해서 운영하기 시작했어요. 예전에는 "GPTBot 허용하면 AI에서 인용된다"는 식으로 단순하게 알려졌지만, 이제는 학습용과 검색 노출용이 완전히 다른 봇이에요.

OpenAI (ChatGPT)

  • GPTBot — AI 모델 학습 데이터 수집용
  • OAI-SearchBot — ChatGPT 검색 결과 노출용
  • ChatGPT-User — 사용자가 직접 요청했을 때 페이지 접근용

Anthropic (Claude)

  • ClaudeBot — AI 모델 학습 데이터 수집용
  • Claude-SearchBot — Claude 내 검색 결과 노출용
  • Claude-User — 사용자 질문에 답하기 위해 페이지 접근용

이 구분이 중요한 이유는, "학습에 쓰이는 건 싫지만, AI 검색에서 인용은 되고 싶다"는 선택이 이제 robots.txt로 분리 설정이 가능해졌기 때문이에요.

# 학습은 차단하고, 검색 노출은 허용하는 예시 (OpenAI)
User-agent: GPTBot
Disallow: /
User-agent: OAI-SearchBot
Allow: /
# Anthropic도 동일하게 분리 가능 User-agent: ClaudeBot Disallow: / User-agent: Claude-SearchBot Allow: /

실시간 인용은 결국 어떤 검색엔진 기반이냐가 핵심

AI 서비스가 질문에 실시간으로 답할 때 인용하는 경로는 각 서비스마다 달라요.

  • ChatGPT — 웹 검색은 Bing 인덱스를 포함한 외부 검색 소스를 활용하는 것으로 알려져 있어요. 검색 노출 관점에서는 Bing 색인 상태를 함께 확인하는 게 유리해요.
  • Gemini — Google이 만든 서비스라 Google 검색 색인을 사용해요. 평소 Google SEO를 잘 하고 있다면 Gemini 인용에 유리해요.
  • ClaudeClaude-SearchBot이 검색 노출을 담당해요. 어떤 검색 색인을 기반으로 하는지는 공개되지 않았어요.
  • Perplexity — 자체 크롤링과 여러 검색엔진을 혼합해서 사용해요.

정리하면 이래요.

AI 서비스 검색 노출용 봇 실시간 검색 기반 챙겨야 할 것
ChatGPT OAI-SearchBot Bing 포함 외부 소스 Bing SEO, Bing Webmaster Tools 확인
Gemini 별도 봇 없음 (Google 검색 직접 활용) Google Google SEO (기존 SEO와 동일)
Claude Claude-SearchBot 미공개 검색엔진 SEO 전반
Perplexity PerplexityBot 자체 + 복수 검색엔진 검색 노출 전반 + 콘텐츠 구조

한국 서비스들이 대부분 Google SEO만 신경 쓰는데, ChatGPT 인용까지 원한다면 Bing 색인 상태도 별도로 확인해볼 필요가 있어요. 위에서 소개한 Bing Webmaster Tools에서 바로 확인할 수 있어요.

"GPTBot 허용하면 AI가 우리 콘텐츠를 인용한다"는 단순화는 이제 맞지 않아요. 학습 데이터 수집과 실시간 검색 노출은 다른 봇이 담당하고, 실시간 인용은 결국 각 서비스가 기반으로 삼는 검색엔진 SEO가 핵심이에요.


마치며

이번 편에서 다룬 내용들은 하나하나는 어렵지 않아요. robots.txt 한 줄, sitemap 경로 한 줄, canonical 태그 한 줄. 근데 분석 서비스를 만들면서 수많은 사이트를 들여다봤을 때 공통적으로 느낀 게 있어요. 이 "한 줄"들이 빠져 있는 경우가 생각보다 훨씬 많다는 거예요. 콘텐츠는 정성껏 만들었는데, 크롤러는 그 페이지에 닿지도 못하는 상황이요.

결국 SEO와 GEO의 출발점은 크게 다르지 않아요. 검색엔진이든 AI 서비스든, 먼저 우리 사이트를 안정적으로 발견하고 이해할 수 있어야 다음 단계로 넘어갈 수 있어요. robots.txt, sitemap, 내부 링크, canonical 같은 기술적 기반은 지금도 가장 중요한 출발점이에요.

좋은 콘텐츠를 만드는 것만큼, 그 콘텐츠가 크롤러에게 제대로 전달되는 구조를 만드는 일 역시 프론트엔드 개발자의 중요한 역할이라고 생각해요.

다음 편에서는 페이지가 발견된 이후, 검색엔진과 AI가 콘텐츠를 어떻게 해석하고 인용하는지, 그리고 어떤 구조가 GEO 관점에서 더 유리한지 살펴보려고 해요.


참고 자료

Google Search Central — 크롤링 및 색인 생성

robots.txt 표준 — RFC 9309

Sitemaps.org — Sitemap 프로토콜

Next.js Docs — Metadata Files: robots.txt

OpenAI — Overview of OpenAI Crawlers (GPTBot, OAI-SearchBot, ChatGPT-User)

OpenAI Help Center — ChatGPT Search

Anthropic — Does Anthropic crawl data from the web? (ClaudeBot, Claude-SearchBot, Claude-User)

Google AI for Developers — Grounding with Google Search

Google Search Central Blog — Inside Googlebot: demystifying crawling, fetching, and the bytes we process

Vercel Blog — The rise of the AI crawler

Perplexity Help Center — How does Perplexity work?

네이버 서치어드바이저 — 웹마스터 도구