본문으로 건너뛰기
뒤로
프로젝트

GitHub Pages 블로그를 구글·네이버 검색에 노출시키기

GitHub Pages로 만든 새 블로그는 SEO 태그를 다 갖춰도 검색에 잘 안 뜬다. 대개 태그가 아니라 검색엔진에 사이트가 있다고 알리는 일이 빠져 있다. 구글 Search Console과 네이버 서치어드바이저에 등록하는 방법과, 등록이 실제로 무엇을 바꾸는지 정리한다.

먼저 확인할 것: 태그는 다 있는가

배포된 사이트가 검색엔진에 어떻게 보이는지부터 본다. canonical이나 사이트맵의 주소는 배포 설정(사이트 URL)을 따라 만들어지므로, 로컬 빌드가 아니라 실제 주소로 확인해야 한다.

SITE=https://loading1031.github.io

# robots.txt 와 사이트맵이 실제로 열리는가
for p in robots.txt sitemap-index.xml sitemap-0.xml; do
  curl -s -o /dev/null -w "%{http_code} $p\n" $SITE/$p
done

# 사이트맵에 글이 다 들어 있는가
curl -s $SITE/sitemap-0.xml | grep -oE '<loc>[^<]*' | sed 's/<loc>//'

# 글 페이지에 title / description / canonical / 구조화 데이터가 있는가
curl -s $SITE/study/database/section-2-acid/ \
  | grep -oE '<title>[^<]*</title>|<meta name="description"[^>]*>|<link rel="canonical"[^>]*>|application/ld\+json'

# 소유확인 태그가 나가고 있는가
curl -s $SITE/ | grep -c 'site-verification'

이 블로그(AstroPaper 테마)의 결과는 이랬다.

항목상태
robots.txt전체 허용, 사이트맵 경로 명시
사이트맵글 전부 포함
title · description · canonical글마다 있음
JSON-LD있음
소유확인 태그0건

테마가 챙겨 주는 태그는 다 있고, 소유확인 태그만 없다. robots.txt는 호스트 루트에 있어야 로봇이 읽는데, username.github.io 사용자 사이트라 문제가 없다. username.github.io/repo 같은 프로젝트 사이트는 repo/robots.txt를 만들어도 읽히지 않는다. 소유확인을 안 했다면 사이트맵을 제출한 적도 없다는 뜻이다. 사이트맵은 파일로 존재해도, 검색엔진이 그 파일을 읽으러 오려면 먼저 사이트를 알아야 한다.

검색 노출은 네 단계다

“검색에 안 뜬다”는 말 하나에 원인이 네 층으로 겹쳐 있다. 어느 층에서 막혔는지에 따라 할 일이 전혀 다르다.

검색에 뜨기까지

사이트맵·RSS 제출

수집 요청

리포트로 확인

발견 이런 URL이 있다

수집 페이지를 긁어 간다

색인 검색 DB에 넣는다

순위 몇 번째에 보여 줄까

소유확인 후 쓸 수 있는 도구

  • 발견: 검색엔진은 주로 이미 아는 페이지의 링크를 따라 새 URL을 찾는다. 생긴 지 얼마 안 됐고 외부 링크도 없는 github.io 사이트는 이 단계에서 멈춰 있기 쉽다.
  • 수집·색인: 발견된 뒤의 일이다. robots.txt, canonical, 구조화 데이터가 여기서 쓰인다.
  • 순위: 색인된 뒤의 일이다. 제목과 본문이 검색어와 맞는지, 다른 곳에서 링크가 걸리는지가 영향을 준다.

테마가 챙겨 주는 건 둘째·셋째 단계다. 첫 단계는 사람이 직접 해야 한다.

Google Search Console: URL 접두어 + HTML 파일

Search Console에서 속성을 추가하면 도메인과 URL 접두어 두 가지를 고르게 된다.

도메인 속성은 github.io에서 쓸 수 없다. 도메인 속성은 DNS에 TXT 레코드를 추가해서 인증하는데, loading1031.github.io의 DNS는 GitHub이 관리한다. 도메인 쪽을 고르면 “이 값을 DNS 설정에 복사하라”는 안내에서 더 진행할 수 없다.

URL 접두어를 고르고 https://loading1031.github.io/를 넣는다. 앞뒤에 공백이 붙으면 “전체 URL 접두어를 입력하라”는 오류가 난다.

인증 방법은 HTML 파일이 간단하다. 받은 googleXXXX.html을 Astro의 public/에 넣으면 빌드 때 사이트 루트로 그대로 복사된다.

public/googleb3f499b4b54cb65b.html   →   https://loading1031.github.io/googleb3f499b4b54cb65b.html

배포가 끝나기 전에 확인을 누르면 실패한다. 파일이 실제로 열리는지 먼저 본다.

curl -s -o /dev/null -w "%{http_code}\n" https://loading1031.github.io/googleb3f499b4b54cb65b.html
# 200 이 나온 뒤에 확인을 누른다

사이트맵 제출과 “가져올 수 없음”

인증이 끝나면 왼쪽 메뉴 Sitemaps로 간다. 입력칸 앞에 https://loading1031.github.io/가 이미 붙어 있으므로 sitemap-index.xml만 넣는다. 전체 주소를 붙여넣으면 주소가 두 번 들어간다.

제출 직후 상태가 가져올 수 없음으로 뜰 수 있다. 먼저 파일이 정상인지 본다.

UA="Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"
for p in sitemap-index.xml sitemap-0.xml; do
  curl -sI -A "$UA" https://loading1031.github.io/$p | grep -iE '^HTTP|content-type'
  curl -s https://loading1031.github.io/$p | xmllint --noout - && echo "$p XML ok"
done

200, application/xml이고 XML 문법도 정상인데 이 상태가 뜨면 구글이 아직 한 번도 가져가지 않은 것일 가능성이 높다. 새 속성에서 흔히 보이고 시간이 지나면 성공으로 바뀐다고 알려져 있지만, 구글이 공식적으로 설명한 내용은 아니다. 확인하는 방법은 두 가지다.

  • 상단 URL 검사에 사이트맵 주소를 넣고 실제 URL 테스트를 누른다. 여기서 가져올 수 있다고 나오면 처리 대기 중이다.
  • 인덱스를 거치지 않도록 sitemap-0.xml도 따로 제출해 둔다.

네이버 서치어드바이저: <head> 안의 메타태그

네이버는 서치어드바이저 → 웹마스터 도구 → 사이트 등록으로 들어간다. 인증은 HTML 태그 방식으로 한다.

<meta name="naver-site-verification" content="..." />

AstroPaper에는 구글용 태그 자리만 있어서 네이버용을 같은 방식으로 추가했다. 설정 파일에 값이 있을 때만 태그가 나간다.

{/* src/layouts/Layout.astro — <head> 안 */}
{
  site.naverVerification && (
    <meta name="naver-site-verification" content={site.naverVerification} />
  )
}

네이버 가이드에 적힌 조건은 세 가지다.

  • 태그는 <head> 안에 있어야 한다. <body>나 <frame> 안에 있으면 검사에서 뺀다.
  • 네이버의 확인 로봇은 자바스크립트를 실행하지 않는다. JS나 meta refresh로 다른 페이지로 넘기면 넘어간 페이지의 태그를 못 본다. 리다이렉트가 필요하면 서버의 301·302로 처리해야 한다.
  • 확인은 브라우저 개발자 도구가 아니라 view-source: 또는 curl로 한다. 개발자 도구는 JS가 고친 뒤의 DOM을 보여 주기 때문이다.

정적 사이트면 셋 다 걸릴 일이 없다. 배포 후 태그가 나오는지만 보고 소유확인을 누른다.

curl -s https://loading1031.github.io/ | grep -o '<meta name="naver-site-verification"[^>]*>'

사이트맵과 RSS 제출

제출은 가이드 문서가 아니라 웹마스터 도구에서 한다. 사이트 목록에서 사이트를 고르고 왼쪽 요청 메뉴로 간다.

메뉴넣는 값
요청 → 사이트맵 제출sitemap-index.xml
요청 → RSS 제출https://loading1031.github.io/rss.xml

네이버도 사이트맵 인덱스를 받는다. RSS 및 사이트맵 제출 가이드에 단일 사이트맵과 “또다른 사이트맵을 포함하는 사이트맵 인덱스” 두 형식이 모두 나와 있다. 제출할 때 검증하는 조건도 같은 문서에 있다.

  • 사이트맵 안의 모든 URL이 소유확인한 사이트와 같은 도메인일 것
  • 10MB 미만, 사이트맵 하나에 URL 50,000개 미만
  • 응답이 느리면 제출이 제한될 수 있음

같은 문서는 RSS보다 사이트맵을 권장한다. RSS는 본문까지 담아서 URL을 많이 넣기 어렵기 때문이다. 둘 다 제출하고 네이버 로봇이 주기적으로 다시 방문하게 두되, 전체 글 목록은 사이트맵이 책임진다고 보면 된다. 새 글은 빌드 때 두 파일에 자동으로 추가되므로 다시 제출할 필요는 없다.

웹 페이지 수집 요청

같은 요청 메뉴의 웹 페이지 수집은 URL 하나를 넣어 “이 페이지를 먼저 긁어 가 달라”고 요청하는 기능이다. 사이트맵이 글 목록 전체를 알린다면, 수집 요청은 특정 글을 앞으로 당긴다. 네이버 가이드에 적힌 성질은 이렇다.

  • 요청해도 로봇이 바로 오지 않는다. 우선순위에 따라 최소 1일에서 몇 주가 걸리니 같은 URL을 매일 다시 넣을 필요는 없다.
  • 사이트마다 요청할 수 있는 양에 제한이 있다.
  • 수집에 성공해도 검색 결과 노출은 보장되지 않는다.

사이트맵을 제출했다면 모든 글을 넣을 필요는 없다. 홈과 먼저 노출되기를 바라는 글 몇 개만 넣는다.

인증값은 공개돼도 괜찮다

구글 값은 파일 이름과 내용에, 네이버 값은 모든 페이지의 HTML에 그대로 드러난다. 그래도 괜찮다.

세 인증 방식은 증명하는 게 같다. “이 주소에 올라가는 내용을 내가 바꿀 수 있다.”

방식값을 두는 곳증명하는 것
HTML 파일루트의 googleXXXX.html루트에 파일을 올릴 수 있다
HTML 태그홈페이지 <head>홈페이지 HTML을 고칠 수 있다
DNS TXT도메인의 DNS 레코드도메인 자체를 관리한다

값은 로그인한 계정과 사이트 주소 조합으로 발급된다. 그 값이 사이트에 나타나면, 사이트를 고칠 수 있는 사람이 그 계정 주인이라는 뜻이 된다. 남이 값을 알아내도 쓸 데가 없다. 자기 사이트에 붙이면 자기 사이트는 증명되지 않고, 내 사이트에는 붙일 권한이 없다. 비밀번호가 아니라 내 사이트에 둘 때만 의미가 있는 표식이다.

소유확인은 순위를 올리지 않는다

네이버 가이드에도 “웹마스터도구에 사이트를 등록하지 않아도 검색 결과에 반영된다”고 적혀 있다. 그럼 왜 하는가. 소유확인은 순위 점수가 아니라 검색엔진에 직접 말을 거는 도구의 열쇠다.

소유확인 없이소유확인 후
발견다른 곳의 링크를 타고 우연히 오기를 기다린다사이트맵·RSS를 제출해 직접 알린다
수집로봇이 언제 올지 모른다특정 URL을 먼저 긁어 달라고 요청한다
색인들어갔는지 알 수 없다리포트로 몇 편이 색인됐는지, 무슨 오류가 났는지 본다
순위—달라지지 않는다

외부 링크가 이미 많은 사이트라면 소유확인 없이도 발견된다. 새 블로그는 외부 링크가 없어서 발견 줄의 차이가 크다.

색인됐는지 확인하는 법

등록 당일에는 확인할 게 없다. 네이버 검증 → 색인 상태 확인에 주소를 넣으면 “URL 검사 결과가 없습니다. 수집 데이터가 없거나…”가 뜨는데, 아직 한 번도 수집되지 않았다는 뜻이다. 며칠 지나 수집 기록이 쌓인 뒤에 본다.

어디서무엇을 보나
Search Console → URL 검사글 하나가 색인됐는지, 안 됐다면 이유
Search Console → 색인 생성 → 페이지색인된 페이지 수와 제외된 이유
서치어드바이저 → 리포트 → 수집 현황로봇이 언제 몇 페이지를 가져갔는지
서치어드바이저 → 검증 → 색인 상태 확인글 하나가 색인됐는지
검색창에 site:loading1031.github.io실제 검색 결과에 뜨는 페이지 (대략적인 확인용)

순위 단계에서 걸리는 것: 제목

색인된 다음부터는 제목이 중요해진다. 이 블로그의 강의 정리 글은 섹션2: ACID, 섹션6: 데이터베이스 파티셔닝 같은 제목을 쓴다. 목록에서 강의 순서를 보여 주기엔 좋지만, “섹션2”를 검색하는 사람은 없다.

같은 블로그에서 행 기반과 열 기반, 모니터링은 왜 열 기반인가처럼 쓴 글은 제목에 검색어가 이미 들어 있다. 목록용 제목을 유지하고 싶으면 <title>에만 검색어형 제목을 따로 쓰는 방법이 있다. 이 블로그에는 아직 적용하지 않았다.

정리: 새 블로그를 만든 날 할 일

  1. 배포된 주소로 robots.txt, 사이트맵, 글 페이지의 title·description·canonical을 curl로 확인한다. 테마를 믿지 말고 결과물을 본다.
  2. Search Console에 URL 접두어 속성을 추가한다(github.io면 도메인 속성은 불가). HTML 파일을 public/에 넣고, 배포 후 curl로 200을 본 다음에 확인을 누른다. 사이트맵을 제출하고, “가져올 수 없음”이 떠도 파일이 정상이면 기다린다.
  3. 네이버 서치어드바이저에 사이트를 등록하고, 메타태그를 <head>에 넣어 인증한다. 요청 메뉴에서 사이트맵(인덱스 파일 그대로)과 RSS를 제출하고, 주요 글 몇 개는 수집 요청을 넣는다.
  4. 제목에 사람들이 실제로 검색할 단어가 들어가는지 본다.

막혔을 때는 네 단계 중 어디서 막혔는지부터 가른다. 태그를 고치는 건 수집·색인 단계의 일이고, 새 블로그가 안 뜰 때는 대개 그보다 앞인 발견 단계에서 막혀 있다.

참고


조회 —



댓글