懒人做法:robots.txt + Nginx 双重屏蔽 GPTBot

 

最近翻 Nginx 访问日志,发现一个叫 GPTBot 的 User-Agent 一直在爬我的网站,频率不低。GPTBot 是 OpenAI 的官方爬虫,但 User-Agent 谁都能伪造,也可能是有人借这个名头在采集内容。

要分辨真假,得拿来访 IP 去比对 OpenAI 公布的 IP 段。我想了想,不管它是真是假,这些流量对我的网站都没什么好处,所以干脆不分辨了,两层一起拦:

  1. robots.txt:告诉守规矩的官方 GPTBot 别来了;
  2. Nginx:不守规矩的、伪装的,直接返回 403。

第一步:robots.txt 禁止 GPTBot

在网站根目录的 robots.txt 里加上:

User-agent: GPTBot
Disallow: /

OpenAI 官方表示 GPTBot 遵守 robots.txt,所以真正的 GPTBot 读到这条规则后就不会再抓取全站。

不过 robots.txt 只是君子协定,伪装者不会理会,所以还需要第二层。

第二步:Nginx 按 User-Agent 拦截

最简单的写法是在 server 块里加:

if ($http_user_agent ~* "gptbot") {
    return 403;
}

~* 表示不区分大小写的正则匹配,GPTBot、gptbot、GPTBOT 都能匹配上。

但这样写有个小问题:robots.txt 也被一起拦了。官方 GPTBot 读不到 robots.txt,就不知道自己被禁止了,可能会一直来撞 403。我更推荐下面这种写法,放行 robots.txt,其他请求一律拒绝。

在 http 块中(通常是 nginx.conf,或 conf.d/ 下的某个文件)加入:

# 识别 GPTBot(不区分大小写)
map $http_user_agent $is_gptbot {
    default   0;
    ~*gptbot  1;
}

# GPTBot 访问 robots.txt 时放行,访问其他路径一律拒绝
map "$is_gptbot:$uri" $deny_gptbot {
    default          0;
    "1:/robots.txt"  0;
    "~^1:"           1;
}

然后在站点的 server 块中加入:

server {
    # ... 原有配置 ...

    if ($deny_gptbot) {
        return 403;
    }
}

这里用到了 Nginx map 的一个特性:精确字符串匹配的优先级高于正则匹配,所以 "1:/robots.txt" 会先于 "~^1:" 生效,robots.txt 就被放行了。

如果你连 403 响应都不想给,可以把 return 403; 换成 return 444;。444 是 Nginx 的特殊状态码,会直接断开连接,不返回任何内容。

第三步:检查配置并重载

sudo nginx -t
sudo systemctl reload nginx   # 或 sudo nginx -s reload

第四步:验证效果

用 curl 模拟 GPTBot 访问:

# 访问首页,应返回 403
curl -I -A "Mozilla/5.0 (compatible; GPTBot/1.0; +https://openai.com/gptbot)" https://你的域名/

# 访问 robots.txt,应返回 200
curl -I -A "GPTBot" https://你的域名/robots.txt

# 普通 UA 访问,应正常返回 200
curl -I https://你的域名/

过一段时间,再从日志里看看拦截效果:

grep -i gptbot /var/log/nginx/access.log | awk '{print $9}' | sort | uniq -c

这条命令统计 GPTBot 请求的状态码分布。正常情况下,应该绝大多数是 403,只有少量 robots.txt 请求返回 200。

几点说明

这个方案防不了换 UA 的爬虫。 按 User-Agent 拦截,只对"自称 GPTBot"的请求有效。如果对方换个 UA 继续爬,这招就失效了,需要配合 limit_req 限流、按 IP 封禁或 WAF 来处理。不过对于"伪装成 GPTBot"的这类流量,这个方案正好能拦住:它既然自称 GPTBot,那就按 GPTBot 处理。

以后想区分真假也不难。 OpenAI 公开了 GPTBot 的 IP 段(在 openai.com/gptbot.json 发布)。可以把日志里的来访 IP 与之比对。不在列表里的,基本就是冒充的。

只屏蔽 GPTBot 不影响其他爬虫。 OpenAI 还有 OAI-SearchBot(用于 ChatGPT 搜索)和 ChatGPT-User(用户在对话中触发的访问)等其他爬虫,它们的 User-Agent 不同,上面的规则不会拦到。如果你希望网站继续出现在 ChatGPT 的搜索结果里,保持现状即可。如果想一并屏蔽,可以在 robots.txt 和 map 里照样加上它们的 UA。

用了 CDN 的话,可以在 CDN 层拦。 如果网站前面有 Cloudflare 之类的 CDN,在 CDN 的防火墙规则里按 UA 拦截更省事,请求根本不会到达源站。不少 CDN 也提供了一键屏蔽 AI 爬虫的开关。

总结

robots.txt 负责礼貌地劝退官方爬虫,Nginx 负责把不守规矩的挡在门外。两层加起来改动不到二十行,不用研究真假,一劳永逸。

posted @ 2026-10-14 12:28  sherlock-merlin  阅读(18)  评论(0)    收藏  举报