·9分で読める

Django・PythonでAIクローラーをブロックする方法

DjangoやFastAPIなどPythonフレームワークを使ったWebサイトでAIクローラーをブロックする実装方法を、Middleware・デコレーター・設定ファイル別に解説します。

DjangoPythonFastAPIAIクローラーブロック

Django・PythonでAIクローラーをブロックする方法

PythonフレームワークでAIボットをブロックする必要性

Next.jsやNginxの事例は多く紹介されていますが、DjangoやFastAPIなどPythonで構築されたWebサービスへの対応はあまり解説されていません。このガイドではPythonフレームワーク向けの具体的な実装方法を紹介します。

Django:Middlewareでブロック

Djangoの場合、カスタムMiddlewareを作成するのが最もクリーンな方法です。

ai_block/middleware.py を作成

import re
from django.http import HttpResponseForbidden

AI_BOT_PATTERN = re.compile(
    r"GPTBot|OAI-SearchBot|ClaudeBot|anthropic-ai|"
    r"PerplexityBot|Google-Extended|Amazonbot|Bytespider|"
    r"CCBot|cohere-ai|MistralBot|Diffbot",
    re.IGNORECASE
)

class AIBotBlockerMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        ua = request.META.get("HTTP_USER_AGENT", "")
        if AI_BOT_PATTERN.search(ua):
            return HttpResponseForbidden("Access denied")
        return self.get_response(request)

settings.pyに登録

MIDDLEWARE = [
    "django.middleware.security.SecurityMiddleware",
    "ai_block.middleware.AIBotBlockerMiddleware",  # ← 追加(上部に配置)
    "django.contrib.sessions.middleware.SessionMiddleware",
    # ... 以下省略
]

Django:robots.txtビューの実装

Djangoではrobots.txtも動的に生成できます:

# urls.py
from django.urls import path
from .views import robots_txt

urlpatterns = [
    path("robots.txt", robots_txt),
    # ...
]

# views.py
from django.http import HttpResponse

def robots_txt(request):
    lines = [
        "User-agent: GPTBot",
        "Disallow: /",
        "",
        "User-agent: ClaudeBot",
        "Disallow: /",
        "",
        "User-agent: PerplexityBot",
        "Disallow: /",
        "",
        "User-agent: Google-Extended",
        "Disallow: /",
        "",
        "User-agent: Amazonbot",
        "Disallow: /",
        "",
        "User-agent: Bytespider",
        "Disallow: /",
        "",
        "User-agent: *",
        "Allow: /",
        "Sitemap: https://yourdomain.com/sitemap.xml",
    ]
    return HttpResponse(
        "\n".join(lines),
        content_type="text/plain"
    )

FastAPI:Middlewareでブロック

FastAPIではStarlette Middlewareを活用します:

import re
from fastapi import FastAPI
from starlette.middleware.base import BaseHTTPMiddleware
from starlette.requests import Request
from starlette.responses import Response

AI_BOT_PATTERN = re.compile(
    r"GPTBot|OAI-SearchBot|ClaudeBot|anthropic-ai|"
    r"PerplexityBot|Google-Extended|Amazonbot|Bytespider|"
    r"CCBot|cohere-ai|MistralBot|Diffbot",
    re.IGNORECASE
)

class AIBotBlockerMiddleware(BaseHTTPMiddleware):
    async def dispatch(self, request: Request, call_next):
        ua = request.headers.get("user-agent", "")
        if AI_BOT_PATTERN.search(ua):
            return Response("Access denied", status_code=403)
        return await call_next(request)

app = FastAPI()
app.add_middleware(AIBotBlockerMiddleware)

FastAPI:依存性注入でエンドポイント単位にブロック

全体ではなく特定のエンドポイントだけブロックしたい場合:

from fastapi import Depends, HTTPException, Request

def block_ai_bots(request: Request):
    ua = request.headers.get("user-agent", "")
    if AI_BOT_PATTERN.search(ua):
        raise HTTPException(status_code=403, detail="AI crawlers not allowed")

@app.get("/articles/{article_id}", dependencies=[Depends(block_ai_bots)])
async def get_article(article_id: int):
    # ...
    pass

Flask:before_requestフック

import re
from flask import Flask, request, abort

AI_BOT_PATTERN = re.compile(
    r"GPTBot|ClaudeBot|PerplexityBot|Google-Extended|Amazonbot",
    re.IGNORECASE
)

app = Flask(__name__)

@app.before_request
def block_ai_bots():
    ua = request.headers.get("User-Agent", "")
    if AI_BOT_PATTERN.search(ua):
        abort(403)

レート制限と組み合わせる

完全ブロックではなくレート制限でコスト増を狙うアプローチも有効です(slowapi使用):

from slowapi import Limiter
from slowapi.util import get_remote_address

limiter = Limiter(key_func=get_remote_address)

@app.get("/content")
@limiter.limit("10/hour")  # AIボット向けに厳しく制限
async def get_content():
    pass

アクセス状況の可視化

どのAIボットがどの頻度でアクセスしているかを把握するには、AI Access Monitorが便利です。1行のJavaScript、またはAPIエンドポイント経由でPythonバックエンドからも利用できます。

import httpx

async def log_to_monitor(ua: str, url: str, site_id: str):
    """AI Access MonitorにアクセスをPOSTする例"""
    async with httpx.AsyncClient() as client:
        await client.post(
            "https://monitor-api.microforge.works/collect",
            json={"site_id": site_id, "ua": ua, "url": url},
            timeout=2.0  # fire-and-forget
        )

まとめ

PythonフレームワークでのAIボットブロックは、Middlewareを使えばわずか20行程度で実装できます。robots.txtと組み合わせた多層防御で、コンテンツを守りましょう。

AI Access Monitor

まず計測から始めよう

1行のコード追加で、AIクローラーの計測を今日から開始。無料・設定不要。

無料で始める →