⚙️Backend

검색 엔진 노출 속도 UP! IndexNow API로 블로그 글 발행 자동화 구축기

IndexNow API로 블로그 글 발행 자동화 구축기: 검색 엔진 노출 속도를 높이는 IndexNow API 연동 방법을 알아봅니다.

📅 2026년 5월 10일·📖 10분 읽기·👁 38

기술 블로그 새 글을 발행했는데, 검색 엔진에 바로 노출되지 않아 답답했던 경험, 다들 한 번쯤 있으실 겁니다. 특히 Bing이나 Yandex 같은 검색 엔진은 IndexNow API를 통해 신속하게 글 발행 사실을 알릴 수 있다고 하더라고요. 그래서 저도 이 기능을 블로그에 도입해보기로 했습니다.

시도와 함정

처음에는 services/indexnow_service.py에 글 발행 시 IndexNow API를 호출하는 헬퍼 함수들을 만들었습니다. BlogRepository.update_status 메서드에서 글 상태가 'published'로 바뀌면 asyncio.create_task를 써서 비동기적으로 ping을 보내도록 코드를 짰죠.

# services/indexnow_service.py (일부)
import asyncio
import httpx

async def ping_urls(urls: list[str], api_key: str): async with httpx.AsyncClient() as client: for url in urls: try: response = await client.post( "https://api.indexnow.org/submit-url", json={"url": url, "key": api_key} ) response.raise_for_status() print(f"Successfully pinged {url}") except httpx.HTTPStatusError as e: print(f"Error pinging {url}: {e}") except Exception as e: print(f"An unexpected error occurred for {url}: {e}")

async def ping_blog_post(post_url: str, api_key: str): await ping_urls([post_url], api_key)

BlogRepository.update_status (일부)

async def update_status(self, post_id: int, new_status: str): # ... 기존 로직 ... if new_status == 'published' and INDEXNOW_KEY: post = await self.get_post_by_id(post_id) # 실제로는 post 객체에서 URL 가져와야 함 asyncio.create_task(ping_blog_post(post.url, INDEXNOW_KEY)) # ...

관리자 API 엔드포인트도 하나 만들어서 수동으로 ping을 날릴 수 있게 했습니다. public/<KEY>.txt 파일도 생성하고 미들웨어까지 설정했는데, 이게 웬걸, 아무리 해도 ping이 제대로 날아가지 않더라고요. 3시간 동안 삽질한 끝에 발견한 건, IndexNow API에서 요구하는 소유권 증명 파일의 경로가 제가 생각한 것과 다르다는 점이었습니다. /public/<KEY>.txt가 아니라, 그냥 /KEY.txt로 접근해야 하는 경우가 있더라고요.

원인

결국 문제는 IndexNow API의 소유권 증명 파일 검증 방식에 있었습니다. 제 설정은 public/ 디렉토리 안에 파일을 두는 방식이었는데, IndexNow는 루트 디렉토리에 직접 파일을 두는 것을 선호하거나, 혹은 특정 경로 설정을 더 엄격하게 요구하는 경우가 있었습니다. 또한, INDEXNOW_KEY 환경 변수가 제대로 설정되지 않아 기능이 비활성화되는 경우도 있었습니다.

해결

이 문제를 해결하기 위해 몇 가지 수정을 가했습니다.

  1. 소유권 파일 경로 수정: public/ 디렉토리를 제거하고, 루트 디렉토리에 직접 KEY.txt 파일을 두도록 설정을 변경했습니다. 웹 프레임워크의 미들웨어를 통해 이 파일을 직접 서빙하도록 구성했습니다.
  2. 환경 변수 확인 강화: INDEXNOW_KEY 환경 변수가 설정되었는지, 그리고 유효한 값인지 추가적으로 확인하는 로직을 넣었습니다.
  3. 비동기 ping 로직 개선: BlogRepository.update_status에서 asyncio.create_task를 사용하여 ping 요청이 메인 요청 흐름을 막지 않도록 했습니다.
# services/indexnow_service.py (수정 후)
import asyncio
import httpx
import os

INDEXNOW_KEY = os.environ.get("INDEXNOW_KEY")

async def ping_urls(urls: list[str]): if not INDEXNOW_KEY: print("INDEXNOW_KEY is not set. Skipping ping.") return

async with httpx.AsyncClient() as client:
    for url in urls:
        try:
            response = await client.post(
                &quot;https://api.indexnow.org/submit-url&quot;,
                json={&quot;url&quot;: url, &quot;key&quot;: INDEXNOW_KEY}
            )
            response.raise_for_status()
            print(f&quot;Successfully pinged {url}&quot;)
        except httpx.HTTPStatusError as e:
            print(f&quot;Error pinging {url}: {e}&quot;)
        except Exception as e:
            print(f&quot;An unexpected error occurred for {url}: {e}&quot;)

async def ping_blog_post(post_url: str): await ping_urls([post_url])

main.py 또는 app.py (미들웨어 설정 예시)

from fastapi import FastAPI

from fastapi.staticfiles import StaticFiles

app = FastAPI()

# 루트 디렉토리에 KEY.txt 파일을 직접 서빙하도록 설정

app.mount("/", StaticFiles(directory=".", html=True), name="static")

# BlogRepository.update_status (수정 후)

async def update_status(self, post_id: int, new_status: str):

# ... 기존 로직 ...

if new_status == 'published' and INDEXNOW_KEY:

post = await self.get_post_by_id(post_id)

asyncio.create_task(ping_blog_post(post.url))

# ...

관리자 API 엔드포인트 예시

@router.post("/blog/indexnow-ping-all")

async def indexnow_ping_all():

all_posts = await blog_repository.get_all_published_posts()

for post in all_posts:

asyncio.create_task(ping_blog_post(post.url))

return {"message": "Initiated ping for all published posts."}

결과

  • 글 발행 후 검색 엔진 노출까지 걸리는 시간이 눈에 띄게 단축되었습니다.
  • INDEXNOW_KEY 환경 변수를 통해 언제든 기능을 켜고 끌 수 있어 안전하게 관리할 수 있게 되었습니다.
  • 관리자 API 덕분에 초기 설정 시나리오나, 혹시 모를 누락된 글들을 한 번에 ping 보내는 작업이 훨씬 수월해졌습니다.
  • asyncio.create_task 덕분에 백그라운드에서 ping이 처리되어 사용자 경험에 전혀 영향을 주지 않습니다.

정리 — 같은 함정 안 빠지려면

  • [ ] IndexNow API 사용 시, 소유권 증명 파일(KEY.txt)의 정확한 경로 설정을 반드시 확인하세요. 웹 프레임워크의 정적 파일 서빙 설정을 체크해야 합니다.
  • [ ] INDEXNOW_KEY 환경 변수는 필수이며, 기능 활성화/비활성화를 위해 안전하게 관리하세요.
  • [ ] 글 발행 시 IndexNow ping은 비동기(asyncio.create_task)로 처리하여 사용자 경험을 저해하지 않도록 하세요.
  • [ ] 관리자 API를 구축하여 전체 글 일괄 ping 기능을 추가하면 초기 설정 및 재처리 시 매우 유용합니다.

태그

#IndexNow API#검색 엔진 최적화#블로그 자동화#기술 블로그#백엔드 개발#API 연동

📨 박주니에게 한마디

스팸·악성 메시지 방지를 위해 구글 로그인 후 메시지를 보낼 수 있어요. 비공개로 전달되며, 운영자 외에는 볼 수 없습니다.

Google 로그인 후 메시지 남기기