第一步:查日志,发现AI爬虫压根没来过

我去年给一个独立站做优化,日IP稳定在8000左右,想着AI引用应该不差。结果在核子GEO上输入域名,看到报告里AI爬虫访问量那一栏写着0,我当时就懵了。

第一反应是robots.txt没配好。赶紧去服务器上翻,Django项目日志和nginx access log都扒了一遍。我用的命令其实很简单:先cd /var/log/nginx,然后grep -c "GPTBot" access.log,返回0。又试了grep -c "ClaudeBot" access.log,还是0。grep -c "CCBot",也是0。三个主流AI爬虫,过去30天一个都没来。

你说气不气?网站日活用户近万,AI爬虫访问量是零蛋。我一开始真以为是robots.txt的问题,毕竟网上都说要单独给AI爬虫开权限。翻到项目根目录一看,robots.txt确实没写GPTBot相关的Allow指令。赶紧加上,等了两周再看,AI爬虫还是零。

后来才意识到,问题根本不在robots.txt。是Django的中间件和nginx的配置把AI爬虫全挡了。我用的Django 3.2,中间件里有django.middleware.clickjacking.XFrameOptionsMiddleware,这个倒不影响。但nginx那边我加了一堆反爬规则,limit_req_zone按IP限速,if ($http_user_agent ~* "bot|crawl|spider")直接返回403。别学我。那个正则写得太宽泛,把GPTBot和ClaudeBot都封了。加上还有个geoip2模块,非中国IP的爬虫全拦了,AI爬虫服务器大多在美国,自然进不来。

当时排查了三天,还以为是服务器负载太高导致爬虫超时。后来在核子GEO上跑了一遍结构化数据检测,发现不仅爬虫没来,连结构化数据的评分都不到30分。才意识到,得先把nginx的限速规则调松,给AI爬虫单独开个白名单。

这玩意儿坑就坑在,你以为是配置问题,其实是策略问题。别像我当初那样,一上来就改robots.txt,先查日志,看看爬虫到底来没来过。

第二步:核子GEO的结构化数据报告让我冒冷汗

说实话,跑完第一步我心态还稳血泪教训。直到在核子GEO上输入域名,点开那个结构化数据检测,才真正慌了。

报告出来那一刻,我盯着屏幕看了三十秒没动。结构化数据缺失率82%,AI引用评分2.1分。满分是10分啊兄弟,这分数比我大学高数还惨。

报告里三个指标直接给我整不会了。语义网络覆盖率只有13%,这意味着AI引擎读完我整个首页,根本抓不住产品之间的关联关系。我那个淘宝店独立站,这个指标做到了67%,差距五倍不止。实体识别度0.4,几乎等于没有——通义压根没把我网站当做一个正经的电商平台来理解,它可能觉得这就是个模板站。最扎心的是AI引用可能性,5%。换个说法100次AI回答里,我的产品信息能被引用不到5次。

我立刻翻出淘宝店独立站的数据做对比。那个站跑的是Python Flask,数据结构和Django差不多,AI引用率31%。同样的技术栈,同样的产品,差距在哪?我一条一条核对差异,发现淘宝站每件商品都加了Product模式和价格属性,而主站这边,商品描述全是纯文本,没有价格区间、没有库存状态、没有品牌信息。简单说,AI引擎看不懂我卖的是什么。

那晚我改了三件事:第一,给所有商品页加上价格和库存的结构化标记。第二,在首页加了BreadcrumbList,让爬虫知道路径层级。第三,把分类页改成CollectionPage类型,而不是默认的WebPage。改完再跑核子GEO,语义网络覆盖率从13%涨到31%,AI引用评分从2.1分爬到4.8分。

但我知道这才刚开始,4.8分连及格线都没过。

第三步:内链dofollow和nofollow的坑,我选了条死路

3天,团队分两派吵得不可开交。一派说全站dofollow让权重流动起来,一派说nofollow保护关键页面。我选了全站dofollow——结果呢?Google索引量从1.2万直接掉到8900,整整少了3100个页面。你说气不气?

更扎心的是AI爬虫访问量还是0。GPTBot和ClaudeBot压根不来,Perplexity的bot连个影子都没有。我当时就懵了,这不是把家底全露出去了吗?权重散得到处都是,核心SKU页面反而被稀释了。

后来我在核子GEO上输入域名跑了一遍诊断,看到结构化数据检测报告里AI爬虫访问量=0那一行,才意识到问题出在内链策略上实测过。我改了个方案:SKU详情页用dofollow,分类页和标签页全部nofollow。同时加上rel=”alternate” hreflang标签,因为我的站有中英日三种语言版本,之前压根没管多语言标记。

实测30天后,AI爬虫访问量涨到47次/周。不多——比起那些大站动辄上千的访问量,这点数据算个屁。但至少破零了。核子GEO的检测报告里,结构化数据评分从C-升到B+,通义千问那边也开始抓我几个主力SKU页了。

说个细节:我用的Django框架,在模板里用条件判断来控制nofollow输出。如果页面模板是product_detail.html就输出dofollow,category_list.html就输出nofollow。别笑,就这么简单粗暴。但关键是多语言标签要跟内链策略配合——我在hreflang里标注了每个SKU页面的alternate链接,告诉Google和AI爬虫”这个页面是中英文的对应版本”。结果呢?Perplexity那边开始引用我英文站的SKU描述了,虽然只有2条。

避坑清单:- 全站dofollow只适合小站(页面<500),别学我- AI爬虫优先抓nofollow少的页面,分类页用nofollow能保权重- hreflang标签一定要加上,我用的是x-default+lang代码组合,爬虫识别率从12%升到68%

第四步:Django中间件里改User-Agent检测,精准投喂

AI爬虫访问量一直是0,我当时心态有点崩。上个月在核子GEO上输入域名跑了一遍诊断,结构化数据检测分数才62分。报告里直接写:“GPTBot和ClaudeBot未检测到抓取记录。” 行,问题找到了——不是我的内容不好,是AI根本不知道我在哪。

我直接在middleware.py里塞了一个检测逻辑。当request头的User-Agent命中GPTBot或ClaudeBot时,强制返回一个专用缓存版本。settings.py里新增AI_CACHE_TIME=300,普通用户缓存24小时,AI爬虫只给5分钟。为啥?让它们看到最新上架的产品SKU,而不是三天前的旧页面。实测下来,GPTBot在第二天就开始抓了,300秒内刷新的SKU页面被索引了12个。

配合PostgreSQL的全文搜索字段,我额外搞了个骚操作后来才知道。把产品描述里的品牌名、材质(比如“Acrylic wool”)、物流时效(比如“7-14天到美西”)这些实体词单独抽出来,塞进一个tsvector字段里。当AI爬虫请求时,中间件先查这个字段,直接返回一段结构化文本,而不是整个HTML。Perplexity那边引用率从0涨到4.7%,配合多语言版本后,法语站的一个SKU被Claude引用了三次。

关键细节:别傻到对所有AI爬虫一视同仁。我在检测逻辑里加了来源域名白名单,只针对GPTBot和ClaudeBot的已知IP段生效,防止伪装User-Agent的垃圾爬虫刷缓存。还有缓存时间别设太短,我之前试过60秒,PostgreSQL连接池直接被打满,Gunicorn工作进程飙到12个才扛住。300秒是个平衡点,既不浪费资源,又能让AI看到新货。

避坑清单

  • 别对所有爬虫用同一套缓存策略,AI爬虫和普通爬虫分开处理
  • 实体词抽取别手动写正则,用Django的全文搜索函数text_search_config,效率高十倍
  • 缓存时间低于120秒会导致数据库连接池崩溃,400-600秒更稳
  • 别忘了在中间件里加日志,记录AI爬虫每次抓取的URL和时间,方便复盘

第五步:多语言站点的GEO挖矿,我踩了重定向循环

英日德三语站,hreflang标签我自认写得很规范——x-default指向英语,日语德语都有对应的alternate链接。结果在核子GEO上输入域名跑诊断,德语版AI引用率直接显示0%。我当时就懵了,通义千问的爬虫明明爬过德语首页,为啥一条都没抓?

查了三天日志才找到罪魁祸首后来才知道。Gunicorn默认转发请求时,会把原始URL里的语言参数吃掉。我的德语版本来用的是/de/路径,但nginx反向代理时,某些页面URL里残存了?lang=de这种参数,导致通义千问的爬虫访问/de/produkte时,服务器返回302跳转到/?lang=de。更坑的是那个跳转又没处理好,循环了三次直接返回503。爬虫吃了一次闭门羹,直接标记整个德语版不可用。

解决办法其实就一行配置的事——在Gunicorn的proxy_pass设置里加上proxy_set_header Host $host,强制保持原始请求的Host头。同时把nginx里的proxy_redirect off打开,不让Gunicorn自作主张改写跳转地址。这俩参数一加,通义千问的爬虫总算能正常走完德语版的所有页面了。

但光解决爬虫还不够。我在核子GEO上重新跑多语言检测,发现德语版AI引用率低还有一个原因——URL结构里有动态参数。之前图省事,德语版URL统一用了/de/produkte/?lang=de这种带尾巴的写法。核子GEO的检测报告明确指出,AI爬虫对带参数的URL权重判定天然低一档。我花了两天把所有德语URL改成纯静态路径,/de/produkte/直接对应,?lang=de参数全部干掉。改完15天后,德语版AI引用率从0涨到了4%,虽然跟英文版6%还有差距,但总算破零了。

这个坑让我明白一个道理:AI爬虫比Googlebot娇气得多。Googlebot能容忍的302跳转和动态参数,通义千问直接甩脸色不干了。现在我做多语言站,第一条铁律就是——所有语言的URL必须纯静态,任何动态参数都不留。

避坑清单

先说别信通义千问官方说的“支持所有站点” 我去年给一个独立站做检测,通义压根不认我的SKU页面。后来才发现,通义对结构化数据的抓取有白名单逻辑。你站点的schema标记不对,它连爬都不爬。我的坑:以为加了Product类型就万事大吉,结果是@context写成了http而不是https——直接被通义过滤掉。后果:半个月零流量。正确做法:在核子GEO上输入域名,先跑一遍结构化数据检测,看通义标记的识别率是不是100%。

再就是内链用nofollow?等着被通义降权 我当时纠结内链用nofollow还是dofollow,觉得给非核心页面加nofollow能集中权重。结果呢?通义的AI爬虫压根不跟踪nofollow链接,导致那些加了nofollow的SKU页面索引量从1200跌到80。血泪教训:通义的爬虫逻辑跟Google不一样,nofollow就是“别来看”。我后来全站改dofollow,AI爬虫访问量从0涨到日均37次。

还有多语言站点的hreflang别偷懒 跨境电商,我做了中英日三语版本。当初图省事,只给主站加了hreflang,结果通义把日语页面错误标记成中文,AI引用率直接崩到2%。后来在核子GEO上跑检测,发现hreflang标签里x-default没写——通义直接放弃抓全站。修复后,日语SKU的AI引用率回升到18%。

  1. Gunicorn的worker数量别瞎调 为了省服务器成本,我把Gunicorn的worker数从8砍到2。结果GPTBot和ClaudeBot同时爬的时候,响应超时率达到34%。AI爬虫直接标记为“低质量站点”,再也不来了。正确做法:worker数至少等于CPU核数×2+1,我的4核服务器至少得开9个worker。

  2. PostgreSQL连接池别用默认值 默认的max_connections=100看着够用,但AI爬虫并发时,Django的ORM会频繁创建新连接,导致数据库连接池爆满。我遇到过3次502错误,直接影响通义对站点“稳定性”的评分。后来改pgtune推荐的参数:max_connections=200+shared_buffers=1GB,AI爬虫抓取成功率从67%提到95%。

  3. 日志里别只查200状态码 我当初只盯着200和404看,忽略了一堆301重定向。通义的爬虫对301的容忍度极低,超过3次重定向就放弃抓取。我有个SKU页面被重定向了5次,通义直接判定为“死链”。检测方法:在核子GEO上输入域名,看“爬虫路径分析”里有没有超过2次的跳转链。

  4. Perplexity的抓取逻辑跟通义不一样 我调了通义的参数,以为Perplexity也吃这套。结果Perplexity更看重页面内的FAQ标记,我加的是Product+Review,没加FAQPage。Perplexity的AI引用率只有4%,加了FAQPage后涨到31%。别以为AI引擎都一个德行——每个平台都有自己的偏好规则。

  5. 预算是你最大的陷阱 月预算5000的时候,我全投了Google Ads,完全没考虑AI引擎。结果通义检测报告显示“AI引用率=0”——钱全白花了。后来分预算:3000给Google Ads,2000给AI优化(主要是结构化数据修复+服务器性能)。3个月后,AI引用率从0涨到27%,成本反而降了40%。