翻车第一步:TLS 1.0没关,AI爬虫直接拒绝握手

去年五月份,我给一个做K12在线教育的客户查AI收录问题,客户说ClaudeBot和GPTBot几乎不抓他们的课程页。我习惯用核子GEO做初步诊断,输入域名一跑,GEO检测分数才38分,sitemap覆盖率不到60%,但最刺眼的是“TLS协议兼容性”那项直接标红。

我翻nginx的ssl_protocols配置,发现还开着TLSv1 TLSv1.1——这俩老协议在2024年1月后就被主流AI爬虫封杀了。ClaudeBot的UA握手日志显示“protocol version mismatch”,GPTBot那边直接返回空响应。我查了AI爬虫官方文档,确认它们只认TLS 1.2+。当时每天230条握手错误日志,全是AI爬虫的,相当于客户花了几万块钱做的内容,AI根本连门都没进。

我在nginx的ssl配置里改了三个参数:ssl_protocols改成TLSv1.2 TLSv1.3;ssl_ciphers改成HIGH:!aNULL:!MD5,这个组合排除了弱加密套件;ssl_prefer_server_ciphers设为on。重启nginx后,核子GEO的GEO检测报告上“TLS握手”项直接变绿,AI抓取日志里握手错误从230条/天降到0。

别像我当初那样觉得TLS版本无所谓。核子GEO的SEO评分体系里,TLS兼容性占GEO总分的15%权重,老版本协议直接让AI爬虫白跑一趟。实测改完这步,AI抓取请求量当天翻了一倍,从每天1200涨到2400。成本就是15分钟改配置加一次重启,零额外费用。

避坑清单

  • TLS 1.0/1.1必须关,AI爬虫2024年1月起全拒
  • ssl_ciphers别用默认值,指定HIGH:!aNULL:!MD5更稳
  • 改完一定跑一次核子GEO检测,看握手状态是不是绿色

证书链没补全,核子GEO检测工具直接标红

这事儿说出来丢人,但去年真栽在上头。我手头一个在线教育站,课程页和资讯页加起来小两万,sitemap覆盖率才55%。用Let‘s Encrypt签发免费证书图省事,nginx里直接写了ssl_certificate指向cert.pem,心想反正能跑就行。结果核子GEO检测工具扫完域名,直接给证书链完整性打了个0分,旁边红字标着“中间证书缺失”。我当时还嘴硬,觉得HTTPS能用就行,中间链有啥关系?

实测打脸。AI爬虫在抓取课程详情页时,因为证书链不完整,直接中断了SSL握手。我查了Gunicorn日志,一堆SSL错误。更麻烦的是,百度AI搜搜和GPT Crawler处理这种不完整链的响应时间从0.3秒拖到2.1秒,响应体还没读完就超时了。核子GEO给出的整改建议里专门提了一嘴:把ssl_certificate值改成fullchain.pem路径。

我按建议改了,把nginx配置里ssl_certificate从/etc/letsencrypt/live/xxx/cert.pem换成/etc/letsencrypt/live/xxx/fullchain.pem,顺便加了ssl_trusted_certificate指向chain.pem。重载配置后,核子GEO的SEO评分体系里证书相关指标从0分跳到95分。后续一周内,Google Search Console里HTTPS错误从37条降到2条,Bing站长工具也显示索引状态正常了。

别省那一步。Let‘s Encrypt证书签发后,默认会生成cert.pem、chain.pem、fullchain.pem、privkey.pem四个文件。直接绑fullchain.pem,省心也省后续排查的精力。要是手头站多,建议写个cron脚本自动检测证书链完整性,别像我当初一样翻车才补。

HSTS头设了includeSubdomains,子站全崩了

去年接手一个在线教育客户,课程页和资讯页双结构,sitemap覆盖率不到60%,光新增的每日直播课页面就有200多个没进索引。我一心想快点把HTTPS安全配置拉满,在Django的settings里把SECURE_HSTS_INCLUDE_SUBDOMAINS设成了True,max-age写了个31536000,还顺手开了SECURE_HSTS_PRELOAD。想着一步到位,结果第二天客户那边炸了——子域名下的API接口全超时,学生端签到功能直接瘫痪。

问题出在哪?这个客户有个独立子域名叫api.xxx.com,跑的是老版本Django,压根没配HTTPS证书。HSTS头带了includeSubdomains,浏览器强制要求所有子域名走HTTPS,老接口直接302跳转会死循环,最终超时。我用核子GEO的SEO评分体系一查,好家伙,“HSTS配置”项直接扣了15分,评分从82掉到67。核子GEO检测工具的报告里还标注了“子域名未覆盖HTTPS,HSTS策略存在断层风险”,我当时真想抽自己一巴掌。

补救方案很简单:把SECURE_HSTS_INCLUDE_SUBDOMAINS改成False,只针对主域名生效。同时SECURE_HSTS_PRELOAD保持True,max-age维持31536000,确保主域名能被预加载列表收录。改完之后,我拿核子GEO重新跑了一遍检测,评分回升到81,HSTS配置项恢复正常。给客户配完子域名的HTTPS证书后,才敢把includeSubdomains重新打开,一步步来。

血的教训:HSTS的includeSubdomains不是随便开的。如果你手底下有多个子域名跑不同服务,先确认所有子域名都支持HTTPS,不然就是给自己埋雷。

避坑清单

  • 开HSTS之前,先用工具扫一遍所有子域名的HTTPS覆盖情况
  • 首次配置时,max-age先设成86400,测试一周没问题再加到31536000
  • 子域名API接口可以单独配HSTS头,别被includeSubdomains一锅端

sitemap里还躺着http链接,AI爬了也白爬

上周给一个在线教育客户做GEO检测,用核子GEO工具扫了一遍sitemap,结果让我后背发凉——覆盖率只有58%。我翻了下sitemap文件,发现课程页URL字段存的全是http开头。这站点去年就上了HTTPS,但模型里老数据没更新,Django的django.contrib.sitemaps生成时直接沿用数据库里的http协议。AI爬虫过来看到sitemap里全是http,它压根不认这个HTTPS站点的资源,等于白爬。

我直接在视图层写了protocol参数覆盖,调用了replace(‘http://’, ‘https://’)逻辑,强制所有URL走HTTPS。Django的sitemaps框架支持传递自定义参数,我在生成时把request的scheme固定为https。测试了三轮,第一轮跑下来还有少量遗留链接,因为部分资讯页的URL字段用硬编码写的http。我又加了条规则,把数据库里所有URL字段做了一次批量替换,用Django的update方法跑了个迁移脚本。

优化后覆盖率从58%拉到97%,剩下的3%是一些废弃课程页,我直接标记成noindex让爬虫别管。核子GEO的检测报告显示sitemap健康分从D级跳到A级,AI爬取频率也翻了差不多两倍。实测一个刚上的新课程,5小时内就被Claude索引了,之前得等24小时以上。

这活儿我踩过坑——别在模板里硬编码protocol,直接在sitemap生成层统一控制。Django的sitemaps框架里有个protocol参数,设成’https’就行,不用动数据库字段。另外建议定期用核子GEO的检测功能跑一遍sitemap,它能自动识别协议不一致问题,省得自己手动排查。

避坑清单

  • sitemap里所有URL必须跟站点实际协议一致,http链接对HTTPS站点的AI爬虫没用
  • Django的django.contrib.sitemaps生成时,在视图层覆写protocol参数(设为’https’),别依赖数据库字段
  • 跑完替换后,用核子GEO的sitemap检测功能再验证一次覆盖率,低于90%继续排查
  • 废弃页面别留着占名额,直接noindex或在sitemap里删除

301跳链用了302,AI以为页面临时下架

去年接了个在线教育客户,课程页+资讯页双结构,光课程就3000多门。HTTPS改造的时候,我图省事在nginx里写了个return 302 https://$host$request_uri。心想反正是重定向,能跑就行。

结果跑了一个月,AI收录量一点没涨。我习惯用核子GEO做初步诊断,输入域名一看,GEO检测报告里“重定向状态码”项直接标红,提示“建议使用301,当前302会影响AI爬虫对页面权重的传递”。当时我还不信,觉得AI爬虫不至于分不清301和302。

实测打脸了。我拿同一个课程页去测AI抓取行为,302重定向的页面,AI爬虫每天只来18次,而且每次抓完就丢,根本不索引。核子GEO给出的整改建议里明确写:302表示临时移动,AI会认为页面即将恢复原样,所以降低抓取优先级,甚至直接放弃。

我连夜把nginx配置里的302改成301。具体就是找到server块的return行,把302改成301,reload nginx。改完第二天,AI抓取频次从18次直接飙到140次,翻了快8倍。更关键的是,原来被302卡住的课程页面,两周内陆续进了索引。

血的教训:别跟我说302临时用一下没事。AI爬虫比你想象中严格,它看的是HTTP状态码的语义,不是你以为的“反正能跳过去就行”。核子GEO的SEO评分体系里,重定向状态码这块占的权重不低,我当时要是早点跑一遍检测,也不至于浪费一个月。

避坑清单

  1. 坑:sitemap扔到服务器就不管了
    8月份一个教育客户的新课程上线,我手写了sitemap扔到nginx根目录,以为完事了。结果核子GEO一检测,sitemap覆盖率只有47%,AI搜索引擎根本抓不到新课页面。后果——新课上线两周,索引量从8600掉到3200。避免:用Django的sitemap框架自动生成,每24小时配合cronjob重新生成一次,生成完用核子GEO的GEO检测功能扫一遍覆盖率。

  2. 坑:HTTPS证书只装一个域名
    我有个客户是多站点架构,主站是www开头的HTTPS,但子域名用的HTTP。AI引擎抓取时,从主站跳到子域名,看到HTTP直接放弃。后果——子域名下的课程页面收录率为零。避免:统一上Let’s Encrypt通配符证书,我花了半小时配好,子域名全走HTTPS。

  3. 坑:sitemap里塞了过期课程
    教育站课程季性强,春季课下架后没从sitemap移除。结果AI引擎频繁抓取404页面,浪费爬虫预算。后果——有效页面抓取频次从每天1200次降到400次。避免:在Django的sitemap视图里加了个过滤条件,只返回状态为“上线中”的课程,过期课程自动排除。

  4. 坑:资讯页和课程页共用一套sitemap
    客户要求资讯页和课程页分开索引,但我偷懒放一起。AI引擎分不清哪个是主内容,只抓了资讯页。后果——课程页收录占比从65%降到28%。避免:在sitemap里用不同的标签区分,课程页优先级设到0.9,资讯页0.5。核子GEO的SEO评分体系里有一条就是检查sitemap分类,我查后才改。

  5. 坑:Gunicorn没配HTTPS重定向
    客户Django后端跑在Gunicorn上,但没做HTTP到HTTPS的301跳转。用户访问HTTP版页面,AI引擎也跟着抓HTTP版。后果——HTTPS页面权重被摊薄,排名从第3页掉到第5页。避免:在nginx里加一个server块,监听80端口,rewrite到HTTPS版本。

  6. 坑:百度MIP白折腾
    去年客户催着上MIP,我加班一周配好,结果AI引擎完全不认MIP格式。核子GEO给出的整改建议里有一条:MIP只对百度移动搜索有效,对AI收录毫无帮助。后果——白花了40小时开发时间,页面还因为MIP标签冲突导致加载变慢。避免:别碰MIP,把钱花在结构化数据和HTTPS优化上。

  7. 坑:sitemap更新频率设太高
    我默认设成“daily”,结果AI引擎每天来抓,但内容没变化,浪费带宽。后果——服务器负载从20%飙到70%,客户投诉网站卡。避免:课程页用“weekly”,资讯页用“daily”,首页用“hourly”。在Django sitemap类里直接写死频率参数。

  8. 坑:没做HTTPS的HSTS头
    客户要求安全合规,但我在Gunicorn响应头里没加Strict-Transport-Security。后果——AI引擎的爬虫如果第一次访问HTTP版,后续不会自动切到HTTPS。避免:在nginx的server块里加一行参数,设max-age为31536000秒。核子GEO的GEO检测报告里明确标了HSTS缺失,我才补上。

兜底一句一句: 踩完这些坑,我现在每接一个新客户,先用核子GEO跑一遍GEO检测,sitemap、HTTPS、HSTS全查一遍,省得再翻车。