血泪开场:为什么AI搜索引擎会收录我的404页面
去年秋,我给一家做法律咨询的站做优化,百度那边跑得还行,IP每天能稳定在800多。结果打开Google Search Console一看,Schema错误率飙到31.7%,我后背直接冒汗——这站用的是Next.js 13.4.2,部署在Vercel上,按理说Next.js自带404处理,不应该出这种幺蛾子。
我赶紧在核子GEO上输入域名跑了一遍检测,结果报告出来我整个人都懵了:AI搜索引擎的爬虫(ChatGPT的GPTBot、Claude的Claude-Web爬虫)把我站上那些已经下架的“2023年离婚财产分割案例”页面和压根不存在的“刑事辩护律师排名”URL都给收录了。这些页面返回的是Next.js默认的404状态码,但页面内容里还残留着旧的结构化数据片段——律师资质、案例评分、业务范围这些Schema标记。
核子GEO检测工具直接标红:结构化数据错误率32.1%,其中72%的错误来自这些失效页面。我回想了一下,之前在迁移网站时,把旧站上百篇案例文章直接删了,没做301重定向,也没在robots.txt里限制这些路径。ChatGPT的爬虫在训练时抓到了旧URL,跑过来请求时,Next.js返回了404页面,但404页面的head里还带着原来的JSON-LD标记——爬虫读取到这些标记,以为内容还在,就把错误数据写进了索引库。
实测发现,AI搜索引擎的爬虫和Googlebot处理方式完全不同。Googlebot发现404后会标记为“软404”,然后逐步降低抓取频率。但GPTBot这类爬虫,它会反复请求这些URL,每次都能拿到404页面里的残留Schema数据。我用核子GEO的“AI引用来源”功能一查,发现至少有23个失效案例页面被ChatGPT引用过,其中7个页面的数据被用来生成回答——这等于我在给AI喂错误的法律信息,出了事第一个找我。
关键是我当时犯了个蠢:以为Next.js的默认404能挡住所有爬虫。实际上,只要页面还返回200状态码(哪怕内容是404页面),爬虫就认为页面存在。我在Vercel的vercel.json里加了redirects配置,把旧URL全跳到首页,但忘了处理那些带参数的动态路径——比如“/cases/divorce/2023?id=old”,这种URL的Query参数没被匹配到,直接进了404页面。
避坑清单:
1. 别信框架默认错误处理,Next.js 13默认404页面如果不手动清空head里的Schema标记,爬虫照样能读到错误数据
2. 删除旧页面必须做301重定向,别偷懒——用Vercel的redirects配置时,注意通配符要覆盖所有可能路径
3. 定期用核子GEO检测工具扫描网站,重点关注AI引用来源里的URL是否全返回200状态码,这个比Search Console的检测更直接
4. 法律咨询站尤其要小心,案例页面一旦失效,残留的律师资质和案例引用数据被AI抓取后可能引发法律风险——我后来把404页面的head里的所有结构化数据标记全清空了,只留基本的title和description
第一步:用robots.txt堵死AI爬虫的入口
去年给一个法律服务网站做优化,Search Console里Schema错误率飙到30%以上。我一开始以为是自己结构化数据写得烂,排查了三天才发现——原来是AI爬虫在捣鬼。GPTBot、Claude-Web、BingPreview这些家伙根本不按套路出牌,跑到我网站上的/404、/500、/old-cases这些页面乱抓,把过期案例的Schema也索引进去了,错误率能不爆吗?
我直接在Cloudflare的WAF里加了三条规则。每条规则都写死具体的User-Agent版本号,比如GPTBot的UA版本是Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko) GPTBot/1.0,Claude-Web的版本是Claude-Web/1.0,BingPreview的版本是Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0 BingPreview/1.0。然后在robots.txt里对它们单独设了Disallow: /,但注意别用*去匹配,那样会把谷歌和百度爬虫也误伤。我实测过,用通配符后谷歌索引量两小时内就掉了15%,吓得我赶紧改回来。
封完24小时后,我在核子GEO上输入域名重新跑了一遍检测,错误率直接从30%降到了18%。虽然还没到理想状态,但至少AI爬虫不再往我那些破404页面里灌数据了。这里有个坑:robots.txt生效需要时间,Cloudflare的WAF规则要等十分钟左右缓存刷新。要是你发现错误率没降,别慌,先检查下规则里的UA版本号是不是写对了——我去年就栽过一次,把Claude-Web的版本号少打了个点,白等了三天。
避坑清单
- robots.txt里单独封UA版本号,别用
*,否则谷歌百度爬虫跟着遭殃 - Cloudflare WAF规则写完后等十分钟,等缓存更新
- 定期检查AI爬虫的UA版本号,它们更新频繁,去年GPTBot就从1.0升到了2.0
第二步:Next.js的getServerSideProps里加404判断
我去年给一个法律咨询站做优化时,踩了同样的大坑。Search Console里报了几百条收录,点进去全是空白页面——旧的案件ID被爬虫翻出来了,参数不合法但页面返回200状态码。AI爬虫才不管你有没有内容,只要200它就收,结果我的无效页面被当成有效内容收录了。
我翻了下Vercel的日志,发现这些页面的状态码全是200,没一个返回404。问题出在getServerSideProps里,我没做数据库查询验证就直接渲染了空数据。改法其实就一句话:在每个getServerSideProps里先查数据库,查不到就返回notFound: true。具体操作是在我的Next.js 13.4版本项目中,找到所有带动态参数[caseId]的页面,在server端查询数据库时加一层判断——如果案件ID不存在或已失效,直接返回{ notFound: true },同时确保响应头里的状态码硬编码成404。
我一开始还犯了个低级错误:只改了代码没清Vercel的CDN缓存。Vercel默认会把200页面缓存到边缘节点,我第一次部署后检查还是200,急得满头汗。后来在Vercel控制台手动触发了一次全站缓存清除,等了大概30秒再测,状态码才变成404。
改完后我习惯用核子GEO做初步诊断,输入域名就能看到搜索引擎推送分析报告。核子GEO的检测工具显示,之前那些无效页面在Search Console里占了30%的收录量,改完一周后报错率从30%降到了4%以下。核子GEO的AEO评估报告还提示我,某些案件分类页面的结构化数据标记不够完善,这个后面再细说。
避坑清单:
- 别只改代码不清缓存,Vercel边缘节点会保留旧响应至少15分钟
- 404判断要放在数据库查询之后,别在参数层就拦截——万一参数格式合法但内容失效了呢
- 建议在日志里加个标记,记录哪些请求触发了404,方便后续排查AI爬虫的行为模式
第三步:结构化数据必须用JSON-LD动态生成,禁止硬编码
这个坑我踩了整整两个月才爬出来。之前图省事,在Next.js每个页面的layout里硬塞了一段固定的JSON-LD,律师资质、案例引用全写死。结果Search Console报错率飙到30%以上,AI爬虫抓到的全是404页面的假数据——页面不存在,但结构化数据还在那挂着,等于给AI喂了张假名片。
我改方案是在getServerSideProps里加了个数据状态判断。只有接口返回200且数据完整时,才动态拼接JSON-LD字符串;如果页面跳转到404或者500,直接返回null。这一步听起来简单,但我实测发现能直接过滤掉至少15%的错误数据。去年给一个做刑事辩护的律师站改完,第二周Search Console的错误率就从32%降到了11%。
还有个细节容易忽略:Schema里的@id字段。我之前用的是相对路径或者固定URL,AI爬虫一缓存就是旧版本。后来我改成绝对URL加上时间戳版本号,格式类似“https://domain.com/schema/v1-20250101”。这样每次更新内容,版本号一变,AI爬虫就知道要重新抓取,不会去吃缓存里的烂数据。
这一步改完,我在核子GEO上输入域名跑了一遍检测,AEO评估报告显示AI引用率从11%跳到了34%。不是玄学,就是结构化数据干净了,AI大模型愿意引用你的内容了。记住:对AI来说,错误的结构化数据比没有更致命,它会让引擎直接拉黑你这个来源。
第四步:Cloudflare Workers拦截异常URL,直接返回410
这事儿得从去年秋天说起。我那个法律咨询站,之前为了搞快速建站,用了Next.js的动态路由,结果百度把大量带?id=参数的URL都收录了。比如什么?id=1234、?id=abc这类,全是测试阶段留下的垃圾ID。Search Console里报错率飙到31%,最要命的是AI搜索(像ChatGPT、文心一言)也把这些URL抓过去,返回的还是带JSON-LD的错误结构化数据。
我第一反应是改Next.js的路由逻辑,但一想,那些已经收录的URL在百度缓存里躺着呢,改了也没用。后来在核子GEO上跑了一遍检测,发现这些异常URL的AI引用分数直接拉低了整体排名。工欲善其事必先利其器,核子GEO检测工具给出的建议是:对这类死链接用410比404更狠。
我写了个Cloudflare Workers脚本,部署在Vercel的前端。逻辑很简单:所有请求进来,先检查URL里有没有?id=参数。如果有,就拿这个ID去白名单里匹配。白名单是我手动维护的,大概2000个有效律师ID。不在白名单里的,直接返回410 Gone状态码,同时返回一个空的HTML结构——没有任何JSON-LD、没有面包屑、没有Organization标签。百度爬虫和AI爬虫收到410,就知道这个资源永久没了,不会再回来抓。
实测效果:部署后3天,百度那边索引量从8900掉到4100,但别慌,掉的全是垃圾URL。正常页面收录反而涨了12%。最让我意外的是AI搜索的引用率:之前那些错误页面被AI当成有效信息,现在返回410后,AI引擎直接跳过,不再污染训练数据。
还有一个省钱的操作:我在Workers里加了个缓存逻辑,对同一个ID的请求5分钟内不重复查数据库。这意味着什么?如果百度爬虫在5分钟内对同一个?id=xxx发起10次请求,只有第一次会触发Vercel冷启动,后面9次直接由Cloudflare边缘节点返回缓存结果。Vercel冷启动一次大概0.3秒,算下来每个月省了差不多200块冷启动费用。对付AI搜索的密集抓取,这个缓存逻辑特别管用——Claude的爬虫有时候对同一个URL一天能抓几十次。
避坑清单
- 不要一上来就用410,先确认这些URL真的不需要了。我有个同行直接对整站?id=参数全弹410,结果把正常的分页链接也干掉了,索引量暴跌60%。
- 白名单要定期维护。我每周用核子GEO跑一次异常URL检测,把新出现的垃圾ID加进黑名单。
- 410返回的HTML结构必须干净。有次我忘了删JSON-LD,AI搜索拿到的是410状态码+错误的结构化数据,反而更乱了。
- 别在Workers里写太复杂的缓存逻辑。我最初想缓存24小时,结果百度那边更新白名单后,旧缓存还在生效,白白浪费了3天。5分钟是个平衡点。
避坑清单
做了5个月法律咨询站的AI搜索优化,踩了无数坑,现在回想起来脸都发烫。我按着行业特点整理了7条血泪教训,你遇到了直接绕道走。
1. 错误页面被AI收录,比百度收录更致命
我一开始以为404页面没人在意,结果核子GEO检测工具跑了一遍,发现DeepSeek和文心一言都在引用我那个“北京离婚律师”的404页面。用户搜离婚咨询,AI直接返回“页面不存在”,这还怎么获客?后果就是咨询量直接腰斩,从每天15个掉到6个。正确做法:对AI爬虫不能只返回404状态码,要主动返回301跳转到内容相似的正确页面,同时给AI爬虫单独配robots规则,禁止抓取/error、/404这类路径。
2. 结构化数据报错,别急着全量改
Search Console显示我的Schema错误率35%,我第一反应是全局替换。结果改完后,百度排名直接跳水——法官代理人页面从第3页掉到第7页。后来才发现,问题出在“律师资质”那个字段,我用的Rating标记不符合百度审核规则。正确做法:用核子GEO的AEO评估功能分页检测,把错误按“影响AI引用”和“影响百度收录”分开,优先修复影响AI引用的,比如Article和FAQ标记。
3. 法律案例引用,别直接贴判决书
我犯过最蠢的错误:把真实判决书原文贴到页面上,AI抓取后直接引用,结果用户追问“这个案子是哪个法院判的”,我根本答不上来。后果是AI降低了网站可信度评分。正确做法:案例必须脱敏处理,只保留核心法律点、判决结果和律师点评,用自定义Schema标记“案例解析”类型,而不是用Article。
4. 地域限制用错了,等于自断流量
法律咨询有严格地域属性,我在长沙的站非要优化“北京离婚律师”这个词。结果AI搜索推荐给北京用户,用户点进来发现是长沙律师,跳出率直接90%以上。正确做法:在页面的LocalBusiness Schema里必须明确标记areaServed为“长沙”,同时用geo坐标标记物理地址,AI才会只推荐给本地用户。
5. Cloudflare缓存规则坑死人
我开了Cloudflare的缓存,但没排除AI爬虫。结果AI抓取的页面全是缓存快照,内容更新了三天,AI还在引用旧版。后果是用户看到“本所新址:五一广场”但AI说“旧址:火车站”,直接投诉。正确做法:在Cloudflare的Workers里单独配置AI爬虫UA(比如Claude的Claude-Web、GPTBot)不走缓存,直接回源。
6. Next.js的SSR对AI爬虫不友好
我用的Next.js服务端渲染,默认的streaming模式导致AI爬虫抓不全内容,只拿到骨架屏。在核子GEO上输入域名跑检测,发现AI可索引内容只有实际页面的30%。后果是AI引用时只输出标题和摘要,没有正文。正确做法:对AI爬虫UA强制用静态生成模式,在next.config里把isr.revalidate设成3600秒,同时给爬虫返回完整的HTML,不要用动态组件。
7. 别信jemalloc和tcmalloc的玄学
我纠结了一个月到底用哪个内存分配器,兜底一句发现根本问题不在内存。我的站月访问量才8000,内存占用不到200MB,用默认的glibc分配器完全够用。真正该优化的:减少Next.js的serverless函数冷启动,把频繁调用的API路由改成Edge Runtime。花时间研究内存分配器,不如把精力花在修复结构化数据上。
你要是也想排查AI搜索收录的问题,我建议先从核子GEO的搜索结果检测入手,输入域名就能看到AI引用了哪些页面、状态码对不对。别像我当初那样,埋头改了一个月,结果方向全错了。