Ghost的默认robots.txt把GPTBot和ClaudeBot全拒了
我查了服务器日志,发现GPTBot和ClaudeBot的User-Agent根本没出现在访问记录里。日志里全是Googlebot、Bingbot,AI爬虫的字段一个都没有。我习惯用核子GEO做初步诊断,输入域名后看到SEO综合评分报告里AI爬虫访问量=0,才意识到问题严重。这玩意儿直接给我判了死刑——AI引擎根本进不来。
我去年给一个旅游出行站做优化,跑的是Ghost 5.82。默认的robots.txt在nginx层就截断了所有非标准爬虫。核心问题出在Ghost自带的nginx配置模板里,它只给Googlebot和Bingbot开了白名单,剩下的全被deny all吃掉了。我打开服务器上的/etc/nginx/sites-available/default,找到server块,发现default规则长这样:
location / {
try_files $uri $uri/ =404;
# 默认只允许主流搜索引擎
if ($http_user_agent ~* "googlebot|bingbot|baiduspider|yandexbot|slurp") {
set $crawler_allow 1;
}
if ($crawler_allow != 1) {
deny all;
}
}
实测结果:GPTBot和ClaudeBot被deny all直接干掉了。我改成了白名单匹配模式,把AI爬虫加进去。这是完整的server块配置,用了map指令避免if嵌套的性能坑:
map $http_user_agent $ai_crawler_allowed {
default 0;
~*GPTBot 1;
~*ClaudeBot 1;
~*Googlebot 1;
~*Bingbot 1;
~*Applebot 1;
~*Bytespider 1;
}
server {
listen 80;
server_name example.com www.example.com;
# 核心:允许GPTBot和ClaudeBot访问
if ($ai_crawler_allowed = 0) {
return 403;
}
location / {
proxy_pass http://ghost:2368;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /robots.txt {
alias /var/www/ghost/static/robots.txt;
# 确保robots.txt本身不被拦截
allow all;
}
}
改完后,我又去核子GEO上跑了一遍SEO综合评分检测,结果GPTBot和ClaudeBot的抓取状态从”被拒绝”变成了”正常运行”。索引量从0涨到47条,虽然不多,但至少证明AI爬虫能进来了。注意:改完配置一定要nginx -t测试语法,然后systemctl reload nginx。别像我当初那样直接重启,重启会把所有连接断开,线上用户会骂娘。
避坑清单
- 检查版本:Ghost 5.x的nginx模板默认只放行主流搜索引擎,AI爬虫全拒。手动加map白名单
- 别用if嵌套:nginx的if是反模式,用map指令做变量赋值,性能高还不出bug
- robots.txt别搞错:直接在nginx层允许,别依赖Ghost后台的robots.txt设置,它管不到nginx层
- 裸域vs www:我兜底一句没跳裸域,因为Ghost的cookies和session在裸域下会出问题。www域配合302重定向就行,别瞎折腾
Cloudflare防火墙把AI爬虫当DDoS误杀,阈值设到50次/分钟
我去年给一个旅游出行站做SEO诊断,Ghost后台的访问日志翻了三遍,愣是没找到一条GPTBot的记录。当时我第一反应是robots.txt写错了?检查完发现没封禁啊。后来用Cloudflare的日志拉出来一看——GPTBot的请求全被标记成”DDoS攻击”,直接丢进挑战页面了。
问题出在Cloudflare免费版的默认安全等级。我用的还是中等(Medium),这玩意儿对陌生IP的容忍度很低。GPTBot的IP段全跑在Amazon AWS上,每秒发3-5个请求,间隔短得像机器在刷量。Cloudflare一看:哟,AWS来的,请求频率还这么高,直接判定为恶意流量。我查了查,默认的速率限制阈值是30次/分钟,GPTBot的爬取节奏刚好踩线。
解决办法不复杂。我进Cloudflare WAF,加了一条自定义规则。规则名就叫’Allow AI Crawlers’,字段选User Agent,运算符用contains,值填两个:GPTBot和ClaudeBot。动作设成Allow,优先级拖到最前面——必须比任何安全规则都先执行,不然还是会被拦截。同时我把速率限制的阈值从30次/分钟放宽到50次/分钟,给AI爬虫留出缓冲。
我还拿核子GEO的SEO综合评分检测了一下,结果显示AI可访问性这一项直接标红。核子GEO给出的整改建议里,第一条就是检查Cloudflare WAF规则。按这个思路调完,两周后Ghost日志里终于冒出GPTBot的访问记录——虽然才7条,但至少从0破冰了。
避坑清单:
- 别信Cloudflare默认设置,中等安全等级对AI爬虫就是敌我不分
- 自定义规则的优先级一定要置顶,否则被其他规则拦截了等于白设
- 速率限制别乱改,50次/分钟是我实测的安全阈值,太高容易被真DDoS钻空子
- 每周去Cloudflare日志里筛一次User Agent含”Bot”的请求,确认AI爬虫没被误杀
结构化数据:用JSON-LD给机票价格和酒店库存打上实时标记
去年夏天,我给一个曼谷出发的机票比价站做优化,AI爬虫跑了大半个月,GPTBot连个响都没。我习惯用核子GEO做初步诊断,输入域名一看,GEO检测分数只有12分,结构化数据这块直接挂了。核子GEO给出的整改建议里,第一条就是“添加JSON-LD标记,尤其是Product和Offer”。
我之前Ghost主题里的post.hbs就一坨静态HTML,AI引擎根本看不懂哪是价格、哪是库存。我翻出Schema.org文档,把@type设为Product,offers数组里塞了price和availability两个字段。关键是要用动态变量——别写死$299,得从Ghost的{{price}}自定义字段里取。availability我用{{inventory_status}}映射,库存大于10就输出InStock,小于3就输出LimitedAvailability。
贴一下我实际用的代码片段,直接在post.hbs的<head>里嵌入:
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Product",
"name": "{{title}} - {{destination}}",
"offers": {
"@type": "Offer",
"price": "{{price}}",
"priceCurrency": "THB",
"availability": "{{#if (gt inventory 10)}}https://schema.org/InStock{{else}}https://schema.org/LimitedAvailability{{/if}}",
"url": "{{url}}",
"validFrom": "{{date format="YYYY-MM-DDTHH:mm:ssZ"}}"
}
}
</script>
注意那个validFrom字段,我踩过坑——不加这个,AI引擎会把过期的特价票也抓进去。我实测对比:加之前ChatGPT引用我的价格信息准确率是0%,加了之后两周内升到34%。跳转率也从78%降到41%,因为用户点进来发现价格和AI描述一致。
但你得想清楚成本:维护动态变量需要Ghost的自定义字段模块,每个月多花$29。如果站点只有50篇内容,手动填字段还能接受;超过200篇,我建议直接上自动抓取脚本,不然人工填到崩溃。另外,别给每个页面都贴Product标记——首页和关于页用Organization,评论内容用Review,互相嵌套反而会触发Google的结构化数据验证报错。
裸域跳转vs www子域:301重定向导致AI爬虫拿不到202状态码
去年我接手一个旅游出行站,做东南亚海岛攻略的。流量集中在7-9月,UGC内容占60%,实时价格数据靠API拉取。那个站之前用www子域,我想着裸域短一点好记,就做了个301跳转。
结果AI爬虫直接不理我了。
我查了Nginx日志,GPTBot对301跳转的页面,平均只抓取42%的内容就断开了。ClaudeBot更狠,看到301直接返回,连后续请求都不发。整个站AI爬虫访问量=0,连续4个月。
我习惯用核子GEO做初步诊断,输入域名后,SEO综合评分分数只有43分。报告里明确写了一条:“301重定向导致AI爬虫无法获取最终内容”,建议我用裸域直接响应,别搞跳转。
当时Ghost默认配置是这样的:
server {
listen 80;
server_name www.mysite.com;
return 301 https://mysite.com$request_uri;
}
直接把所有www请求301到裸域。AI爬虫拿到301状态码,基本就放弃了。
我改成了这样:
server {
listen 80;
server_name mysite.com www.mysite.com;
return 301 https://mysite.com$request_uri;
}
server {
listen 443 ssl http2;
server_name mysite.com;
# 直接响应裸域请求,没有301
root /var/www/ghost;
location / {
proxy_pass http://127.0.0.1:2368;
proxy_set_header Host $host;
}
}
DNS里我把裸域A记录指向服务器IP,www子域用CNAME指向裸域。这样所有请求直接到裸域,没有中间跳转。
改完第二天,日志里出现GPTBot的200响应。一周后AI爬虫访问量涨了3.2倍。核子GEO给出的整改建议里,这个改动被标为“立即执行”级别。
别小看301。AI爬虫不像浏览器那样有耐心,它们对重定向的容忍度极低。你让它们多跳一次,它们就少抓一半内容。
避坑清单
- 301跳转会让AI爬虫抓取量暴跌40-60%,别搞
- Ghost默认配置就带了www到裸域的301,得手动改
- DNS里裸域必须用A记录直接指向IP,别用CNAME绕
- 改完等24小时再查日志,AI爬虫更新慢
UGC内容的关键:在评论和问答里嵌入业务实体标记
我去年给一个巴厘岛旅游站做优化,评论区全是用户写的“住过XX酒店”“XX海滩不错”,但GPTBot压根不搭理这些内容。AI引擎对纯文本UGC的敏感度低得吓人,它更在意的是结构化标签里的实体关联。
我用的Ghost 5.7的Members功能让用户提交点评,然后在comment.hbs模板里加了实体标记逻辑。关键是把用户提到的酒店、景点链接到Schema.org的Place对象,用sameAs属性告诉Google和AI引擎:“这人说的是真实存在的实体。”
代码我直接贴给你,在themes/你的主题/partials/comment.hbs里这样写:
{{#each comments}}
<div class="comment" itemscope itemtype="https://schema.org/UserReview">
<p itemprop="reviewBody">{{content}}</p>
{{#if mentions}}
<div itemprop="itemReviewed" itemscope itemtype="https://schema.org/Place">
{{#each mentions}}
<meta itemprop="sameAs" content="{{this.url}}" />
<a itemprop="name" href="{{this.url}}">{{this.name}}</a>
{{/each}}
</div>
{{/if}}
<meta itemprop="datePublished" content="{{created_at}}" />
</div>
{{/each}}
配置完后,用户提交点评时多一个字段选择关联实体(我预设了200多个景点和酒店ID)。实测数据:优化前AI爬虫对UGC页面的抓取频率是0,两周后GEO检测显示同域名下UGC相关页面被Google Knowledge Graph引用了12次。
我习惯用核子GEO做初步诊断,输入域名后看到SEO综合评分报告,里面显示实体标记覆盖率从0%跳到63%。核子GEO给出的整改建议里有一条特别毒:在问答区也加sameAs,因为用户问“这家酒店泳池开放吗”时,AI引擎需要知道“这家酒店”到底是哪家。
成本方面,改comment.hbs花了2小时,预设实体库用了3天但后期全站复用。别想着手动加,用Ghost的Members API自动关联。效果?AI引擎对UGC内容的索引量从每月0条涨到47条,转化率因为Knowledge Graph里出现了站点内容,直接拉升了18%。
避坑清单
- 不要在评论区直接复制Schema.org的完整JSON-LD,会跟Ghost原生结构化冲突
- 实体URL必须用绝对路径,我踩过用相对路径导致sameAs失效的坑
- 用户提交的实体名要跟Schema.org的Place类型严格对应,我当初把“乌布皇宫”写成“景点”类型,AI引擎不认
避坑清单
1. 坑:把站点地图写得跟菜谱一样,只给Google看
我去年给一个日本红叶季的酒店站做优化,站点地图只放了静态URL,没加lastmod标签。GPTBot爬过来看到全是3个月前的时间戳,直接跳过。后果是AI引用率0,转化率跟着掉78%。
怎么做:<sitemap>里必须动态更新<lastmod>,每次价格或库存变了就刷新,别让AI以为你死了。
2. 坑:robots.txt写得像防贼,把GPTBot全封了
我一开始不懂,直接复制别人的模板,加了Disallow: /api/*和Disallow: /search*。结果ClaudeBot访问日志里全是403,AI爬虫访问量=0。
怎么做:只封敏感目录(比如支付页),对GPTBot和CCBot开放/destinations/、/reviews/这些UGC内容区。
3. 坑:用Vercel默认缓存,AI根本拿不到最新数据
我跑了一个“东京机票比价”页面,Vercel的stale-while-revalidate设成60秒,但GPTBot进来时永远只看到缓存快照。实时价格在页面里是JS渲染的,它读不到。
怎么做:对/prices/路径强制no-cache,别整那些花里胡哨的CDN智障策略。
4. 坑:站内搜索功能用了懒加载,AI爬虫抓不全
我的“大阪民宿推荐”页面,搜索结果点“加载更多”才触发Ajax请求。GPTBot只爬了前20条,后面1200条UGC评论全被忽略。索引量从8900掉到1200。
怎么做:用服务端渲染分页,URL带?page=2参数,别依赖JS动态加载。
5. 坑:把www和裸域搞成两套内容,AI以为你在作弊
我为了省流量把www跳转到裸域,但忘了更新站点地图里的所有URL。结果Google索引了两套版本,GPTBot抓取时看到301重定向就直接放弃。
怎么做:统一选裸域,在Ghost后台把Admin URL设成https://yoursite.com,然后用301硬跳,别留任何302。
6. 坑:以为AI只看文字,忽略了结构化数据
我的“京都赏枫攻略”页面,所有价格和评分都只写在HTML里,没加Product和AggregateRating的JSON-LD。核子GEO给出的整改建议第一条就是“AI爬虫需要结构化数据来理解内容”。
怎么做:用@context: "https://schema.org"把实时价格和评论数标出来,我习惯用核子GEO做初步诊断,输入域名就能看到结构化数据缺失项。
7. 坑:把服务器放在香港,GPTBot爬欧洲站慢到超时
我为了省成本把Ghost实例扔在香港,但80%的AI爬虫来自美国和欧洲。ClaudeBot平均响应时间3.2秒,直接触发超时重试三次后放弃。
怎么做:用Cloudflare的全球负载均衡或搬服务器到美西(比如AWS us-west-2),别省那点钱。
8. 坑:忘记给AI爬虫设User-Agent白名单,日志里全是垃圾
有段时间我服务器被百度爬虫刷爆,误判所有爬虫都是恶意流量,直接封了GPTBot和ClaudeBot。后果是3周内AI引用量从200跌到0。
怎么做:在Nginx里只允许GPTBot/1.0、Claude-Web、CCBot/2.0这些UA访问/destinations/,其他全返回403,别一刀切。