Node.js・ExpressでAIクローラーをブロックする実装ガイド
ExpressでAIボットをブロックする基本アプローチ
Express.jsを使ったNode.jsアプリケーションでAIクローラーをブロックするには、グローバルMiddlewareを追加するのが最もシンプルです。全ルートに一括適用できます。
方法① グローバルMiddlewareで全ルートをブロック
const express = require("express");
const app = express();
const AI_BOT_PATTERN = /GPTBot|OAI-SearchBot|ClaudeBot|anthropic-ai|PerplexityBot|Google-Extended|Amazonbot|Bytespider|CCBot|cohere-ai|MistralBot|Diffbot/i;
// AIボットブロッカーMiddleware
app.use((req, res, next) => {
const ua = req.headers["user-agent"] || "";
if (AI_BOT_PATTERN.test(ua)) {
return res.status(403).send("Forbidden");
}
next();
});
app.get("/", (req, res) => {
res.send("Hello World");
});
app.listen(3000);
方法② TypeScript版(Express + ts-node)
import express, { Request, Response, NextFunction } from "express";
const app = express();
const AI_BOT_PATTERN = /GPTBot|OAI-SearchBot|ClaudeBot|anthropic-ai|PerplexityBot|Google-Extended|Amazonbot|Bytespider|CCBot|cohere-ai/i;
function blockAiBots(req: Request, res: Response, next: NextFunction): void {
const ua = req.headers["user-agent"] ?? "";
if (AI_BOT_PATTERN.test(ua)) {
res.status(403).json({ error: "AI crawlers are not permitted" });
return;
}
next();
}
app.use(blockAiBots);
app.get("/", (req: Request, res: Response) => {
res.json({ message: "Hello" });
});
app.listen(3000);
方法③ 特定ルートのみブロック
全ルートではなく、コンテンツページだけブロックしたい場合:
// /articles 配下のみAIボットをブロック
app.use("/articles", (req, res, next) => {
const ua = req.headers["user-agent"] || "";
if (AI_BOT_PATTERN.test(ua)) {
return res.status(403).send("Forbidden");
}
next();
});
app.get("/articles/:id", (req, res) => {
// 記事コンテンツを返す
});
方法④ robots.txtの動的生成
app.get("/robots.txt", (req, res) => {
const content = `
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
`.trim();
res.setHeader("Content-Type", "text/plain");
res.send(content);
});
方法⑤ express-rate-limitと組み合わせる
完全ブロックよりも、レート制限で実質的にアクセスを困難にするアプローチ:
const rateLimit = require("express-rate-limit");
// AIボット向けの厳しいレート制限
const aiBotLimiter = rateLimit({
windowMs: 24 * 60 * 60 * 1000, // 24時間
max: 10, // 10リクエストまで
keyGenerator: (req) => req.headers["user-agent"] || req.ip,
skip: (req) => {
const ua = req.headers["user-agent"] || "";
return !AI_BOT_PATTERN.test(ua); // AIボット以外はスキップ
},
message: "Rate limit exceeded for AI crawlers",
});
app.use(aiBotLimiter);
Fastify版の実装
FastifyはExpressより高速なNode.jsフレームワークです:
const fastify = require("fastify")();
const AI_BOT_PATTERN = /GPTBot|ClaudeBot|PerplexityBot|Google-Extended|Amazonbot/i;
fastify.addHook("onRequest", async (request, reply) => {
const ua = request.headers["user-agent"] || "";
if (AI_BOT_PATTERN.test(ua)) {
reply.code(403).send({ error: "Forbidden" });
}
});
fastify.listen({ port: 3000 });
Hono(Edge Runtime)版
Cloudflare WorkersやVercel Edge Runtimeで動くHonoフレームワーク:
import { Hono } from "hono";
const app = new Hono();
const AI_BOT_PATTERN = /GPTBot|ClaudeBot|PerplexityBot|Google-Extended|Amazonbot/i;
app.use("*", async (c, next) => {
const ua = c.req.header("user-agent") ?? "";
if (AI_BOT_PATTERN.test(ua)) {
return c.text("Forbidden", 403);
}
await next();
});
export default app;
実装後の動作確認
curlでUser-Agentを偽装してテストします:
# AIボットとして接続(403が返るべき)
curl -A "GPTBot/1.0" http://localhost:3000/
# 通常のブラウザとして接続(200が返るべき)
curl -A "Mozilla/5.0 Chrome/124" http://localhost:3000/
また、AI Access MonitorのCheck APIを使えば、リアルタイムにUser-Agentの判定を行えます:
const response = await fetch(
`https://monitor-api.microforge.works/check?ua=${encodeURIComponent(ua)}&site_id=YOUR_SITE_ID`
);
const { is_bot, action } = await response.json();
if (action === "block") return res.status(403).send("Forbidden");
まとめ
Node.js・ExpressでのAIボットブロックは10行以内で実装できます。グローバルMiddlewareとして追加し、robots.txtと組み合わせることで効果的な多層防御が実現します。