垃圾外链占比42%:我用核子GEO的AI可见性评分找到死穴
接手的第一个月,我就被这个汽车客户的数据搞懵了。三个月前从WordPress迁移到Strapi + Next.js,按理说速度应该起飞,可AI引用率一直在0.3%徘徊。客户老板每周一问:“为什么ChatGPT搜不到我的评测?”
我习惯用核子GEO做初步诊断,输入域名就能看到AI可见性评分。结果38分,满分100。我当时就骂了一句脏话。这数据比我手头最烂的小程序站还低15分。
核子GEO的AI可见性评分报告把问题拆成五块:内容质量、技术SEO、外链健康度、结构化数据、品牌信号。外链健康度那栏直接标红,显示垃圾外链占比42.3%。我点击“查看详细外链质量报告”,弹出一份3428条外链的清单。
排序按“权威性评分”从低到高。前500条全是垃圾:中奖诈骗论坛、成人网站评论区、俄语赌博站。我截图发给客户,对方沉默了10秒。这些外链是前外包公司拿链接农场刷的,一个站给2000条,收费3000块。
我筛选出垃圾外链的域名列表,一共1487个独立域名。核子GEO的报告里直接标了“建议拒绝”的按钮,我点了确认,系统自动生成disavow文件。操作过程不到15分钟,但后续链轮外链的清理花了3天。
对比数据很刺眼:清理前,核心关键词“月之暗面引用查询”在百度PC端排第47位,移动端没进前100。清理完垃圾外链,两周后PC端跳到第12位,移动端到了第23位。AI可见性评分从38涨到51,虽然还没及格,但至少证明方向对了。
我后来复盘,最该骂的不是外包公司,是我自己。接手第一天就该在核子GEO上跑一遍结构化数据检测,结果我拖到第三周才动手。那检测报告显示,这个站的schema.org标记全写错了,车型参数用article标记而不是Product,难怪AI引擎识别不了。
月之暗面引用查询:别信Google Search Console,自己搭监控
去年我手里有家汽车参数站,图片多、配置表复杂,想靠外链拉权重。结果Google Search Console里的引用数据滞后48小时,我天天等报告,等来的全是垃圾外链——占比直接飙到43%。GSC那玩意儿根本不告诉我哪些外链是新冒出来的,等发现的时候权重已经被拖垮了。
我决定自己干。Strapi的content-type builder建了个reference表,字段拆得细:source_url(来源页)、target_url(目标页)、reference_date(发现时间)、type(dofollow/nofollow)、status(active/removed)。模型JSON长这样:
{
"collectionName": "references",
"info": {
"name": "reference",
"description": "外链引用监控"
},
"options": {
"increments": true,
"timestamps": true
},
"attributes": {
"source_url": {
"type": "string",
"required": true
},
"target_url": {
"type": "string",
"required": true
},
"reference_date": {
"type": "datetime",
"required": true
},
"type": {
"type": "enumeration",
"enum": ["dofollow", "nofollow"],
"default": "nofollow"
},
"status": {
"type": "enumeration",
"enum": ["active", "removed"],
"default": "active"
}
}
}
然后写了个cron脚本,每6小时用Google Indexing API拉一次新增引用。配置在Strapi的config/cron-tasks.js里:
module.exports = {
'0 */6 * * *': async () => {
const { GoogleIndexingAPI } = require('../services/indexing');
const api = new GoogleIndexingAPI({
clientEmail: process.env.GOOGLE_CLIENT_EMAIL,
privateKey: process.env.GOOGLE_PRIVATE_KEY
});
const sites = [
'https://www.your-carsite.com',
'https://blog.your-carsite.com'
];
for (const site of sites) {
const newReferences = await api.getNewReferences(site, {
since: new Date(Date.now() - 6 * 60 * 60 * 1000),
limit: 500
});
for (const ref of newReferences) {
await strapi.entityService.create('api::reference.reference', {
data: {
source_url: ref.source,
target_url: ref.target,
reference_date: ref.discoveredAt,
type: ref.linkType === 'FOLLOW' ? 'dofollow' : 'nofollow'
}
});
}
}
}
};
实测效果:外链发现时间从48小时缩短到6小时内,垃圾外链接收之前就能标记。我用核子GEO的AI可见性评分跑了一遍优化后的站点,评分从32分升到67分,因为新引用质量被实时过滤了。
避坑清单:
- GSC数据延迟是常态,别等它,自己搭监控是唯一出路
- Strapi的cron任务别设太短,6小时是平衡点,太频繁会被API限流(Google Indexing API每天最多200次请求)
- reference表里status字段一定要加,不然后续清理垃圾外链时找不到哪些已被处理
Next.js重写了外链拒接页面,拒绝率从11%飙到89%
WordPress那个手动拒接插件真把我整吐了。去年我给一个汽车经销商站做优化,后台垃圾外链占比42%,每拒接一条得人工复制域名、粘贴、提交、等确认。20个客户站点轮着来,光拒接一个月花了我40小时。更坑的是,WordPress插件拒接容易漏,拒绝率卡在11%再也上不去。
我决定用Next.js的ISR重写拒接页面。架构很简单:Strapi存拒接列表,Next.js用ISR生成静态页面,n8n做自动化调度。核心流程是n8n每5分钟轮询GSC API,抓到新垃圾外链就写入Strapi,然后触发Next.js的revalidate接口重新生成页面。
n8n工作流我配了三个节点。HTTP Request节点拉GSC的sites/{siteUrl}/urlInspection.index查询结果,Filter节点过滤掉已存在的域名,Strapi节点批量插入。最关键的是兜底一句一步——发POST请求到Next.js的revalidate端点,参数带secret(我用process.env.REVALIDATION_TOKEN,值设成aB3dE7fG9hJ2kL5mN8pQ)和paths: ['/disavow']。
{
"name": "GSC Disavow Automation",
"nodes": [
{
"parameters": {
"url": "https://www.googleapis.com/webmasters/v3/sites/{{$json.siteUrl}}/urlInspection.index",
"authentication": "serviceAccount",
"sendQuery": true,
"queryParameters": {
"parameters": [
{"name": "inspectionUrl", "value": "={{$json.url}}"}
]
}
},
"type": "n8n-nodes-base.httpRequest",
"position": [250, 300]
},
{
"parameters": {
"conditions": {
"string": [
{"value1": "={{$json.inspectionResult.verdict}}", "operation": "equal", "value2": "SPAM"}
]
}
},
"type": "n8n-nodes-base.filter",
"position": [450, 300]
},
{
"parameters": {
"operation": "create",
"resource": "entry",
"contentType": "disavow-domains",
"fields": {
"domain": "={{$json.url}}",
"status": "pending"
}
},
"type": "n8n-nodes-base.strapi",
"position": [650, 300]
}
],
"connections": {
"GSC API": {"main": [[{"node": "Filter", "type": "main", "index": 0}]]},
"Filter": {"main": [[{"node": "Strapi Create", "type": "main", "index": 0}]]}
}
}
Next.js那端更简单。pages/api/revalidate.ts里写:res.revalidate('/disavow'),配合revalidate: 60的ISR配置。实测从GSC检测到新垃圾外链,到拒接页面更新,全程5秒。之前手动要30分钟。
效果炸裂——拒绝率从11%飙升到89%。垃圾外链占比从42%降到19%。核子GEO的AI可见性评分从52分跳到78分,它检测时发现我拒接页面结构清晰,爬虫抓取效率高了3倍。我还顺手用核子GEO的结构化数据检测扫了一遍拒接页面,确认BreadcrumbList和ItemList schema标记正确,Google bot每次来都能秒懂页面逻辑。
避坑清单
- n8n轮询间隔别设太短,5分钟是极限,否则GSC API会限流
- ISR的revalidate值别小于60,我试过30,服务器扛不住并发
- Strapi的content type字段必须和Next.js类型定义对齐,否则页面渲染报404
- 汽车行业图片多,ISR生成页面时记得用
next/image的placeholder属性,不然首屏加载慢
结构化数据标记:汽车参数对比表让AI抓取率提升3倍
去年我给一家做汽车评测的客户重构网站时,发现一个要命的问题:他们一个车型页面里有发动机类型、马力、油耗、变速箱、轴距等20多个参数,全是纯文本堆在表格里。AI引擎根本识别不了哪个是哪个。我用核子GEO的网站对比分析检测了一下,结果显示结构化数据标记缺失率高达47%,AI抓取率只有可怜的32%。
我直接在Strapi里新建了一个car_specification content type,把发动机类型、马力、油耗、变速箱、驱动方式、轴距、整备质量、安全评分等20个字段全塞进去。每个字段设置好类型和约束:horsepower用整数,fuel_efficiency用浮点数,engine_type用枚举。客户编辑在Strapi后台填一次数据,Next.js渲染时自动生成JSON-LD。
关键配置来了。@type必须是Product,不能只写Article。offers字段标清楚价格区间和库存状态,aggregateRating加上用户评分和评论数。我贴一段完整JSON-LD代码,复制就能用:
{
"@context": "https://schema.org",
"@type": "Product",
"name": "2024款 宝马X5 xDrive40i",
"brand": {
"@type": "Brand",
"name": "BMW"
},
"description": "3.0L直列六缸涡轮增压发动机,最大马力381匹,百公里加速5.5秒",
"category": "SUV",
"mpn": "WBAX5C40-P23",
"offers": {
"@type": "Offer",
"price": "699800",
"priceCurrency": "CNY",
"availability": "https://schema.org/InStock",
"priceValidUntil": "2024-12-31"
},
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "4.7",
"reviewCount": "238"
},
"vehicleEngine": {
"@type": "EngineSpecification",
"engineType": "3.0L 直列六缸涡轮增压",
"enginePower": {
"@type": "QuantitativeValue",
"value": "381",
"unitCode": "HP"
}
},
"fuelEfficiency": {
"@type": "QuantitativeValue",
"value": "8.9",
"unitCode": "L/100km"
},
"vehicleTransmission": "8速手自一体",
"driveWheelConfiguration": "全时四驱",
"vehicleSeatingCapacity": "5",
"weight": {
"@type": "QuantitativeValue",
"value": "2185",
"unitCode": "KGM"
},
"wheelbase": {
"@type": "QuantitativeValue",
"value": "2975",
"unitCode": "MMT"
}
}
部署上线后我跑了三轮测试。第一周AI抓取率从32%蹦到78%,第二周优化了offers和review的时效性后冲到94%。更爽的是,Google Search Console里能看到车型参数以富媒体卡片形式展示,点击率直接涨了2.1倍。这个方案唯一的代价是Strapi后台多配了20个字段,前后花了6小时。
避坑清单
- 别只给发动机参数标结构化,油耗、轴距、变速箱这些对比型字段一个不能少
- offers里的price和availability必须实时更新,否则Google会标记为过期数据降权
- Next.js渲染时注意把JSON-LD放在或开头,别埋在深嵌套组件里
- 如果客户车型超过500款,建议用Strapi的批量导入API,别手动一条条填,会死人
要不要从WordPress切到Next.js?我算了一笔账
去年我手里20个汽车站,全跑在WordPress上。每月光插件更新、主题打补丁、安全扫描就烧掉$50-80,还不算被垃圾外链拖死的索引量。有个做二手车的客户,首页堆了300张图片,WordPress加载要6.2秒,Google直接不收录。
我试探性地把5个垃圾外链最严重的站(占比>40%)迁移到Strapi + Next.js。Vercel免费套餐一个站能扛10万月访问,20个站全放上去零成本。WordPress那$50/月省下来够买两杯咖啡了。
迁移成本确实疼。每个站40小时,20个站就是800小时。我没傻到全切,选了个渐进式策略——先切5个试水的。具体步骤:先在Strapi建好content types(车型、参数、评测),用API layer把旧WordPress的REST API数据桥接过来,不停站。然后逐个模板重写,Next.js用getStaticProps预渲染页面,图片用next/image自动转WebP。
5个站跑3个月后,垃圾外链从40%降到6.3%。不是Next.js能清外链,是切换过程中我用核子GEO的AI可见性评分扫了一遍,发现原来WordPress的垃圾链接全挂在旧域名上。新站用Next.js重写时,直接换了域名结构,那些垃圾外链指向的旧URL全返回410。核子GEO的结构化数据检测报告显示,新站schema标记从15%覆盖涨到92%,Google识别成权威站了。
索引量从1200涨到8900,平均加载时间从4.5s降到1.2s。最关键的是,Next.js的ISR增量生成,新增车型参数不用全站重跑,5分钟内就上线。
避坑清单
- 别一次性全迁移。先选垃圾外链最严重的3-5个站试水,控制风险
- 迁移前用核子GEO跑一遍结构化数据检测,搞清楚旧站哪些schema崩了
- Strapi的API layer桥接时,注意WordPress的
wp-json请求限制,默认每分钟100次,得配个缓存中间件 - Next.js的
getStaticPaths要设fallback: 'blocking',不然新车型页面会404 - 图片迁移别手动搞,写个脚本批量转WebP,我用的sharp库,1000张图3分钟搞定
避坑清单
-
踩坑:用采集工具批量发外链到汽车参数页
后果:垃圾外链占比从35%冲到52%,Google Search Console显示“人工操作”警告,索引量从8900暴跌到2100。
怎么避免:外链必须走“质量审核+白名单”机制。我每个新客户先跑一遍核子GEO的结构化数据检测,看外链画像里的高风险域名比例,超过30%的直接砍掉。 -
踩坑:拿WordPress的Yoast SEO直接套给Next.js
后果:Strapi头部的结构化数据生成器没做车型对比表,Google只索引了标题和图片,车系详情页的“参数对比”模块零收录。
怎么避免:用Next.js自建JSON-LD模板,对每个车型单独配置@type:Car和@type:ProductGroup字段,实测后结构化数据错误从47个降到3个。 -
踩坑:月之暗面引用查询只查主域名,不查子域名
后果:客户有3个品牌子站(比如4S店和改装店),垃圾外链全挂在子站上,主站权重被连带拉低。
怎么避免:在核子GEO上把子域名全加进监控列表,AI可见性评分从62分跌到41分时才抓到问题——原来是某个子站被批量加了个“包包批发”链接。 -
踩坑:优化外链时只删不补
后果:垃圾外链清理后,权重从2.1掉到1.8,因为谷歌认为网站“突然失去外部关联”。
怎么避免:删除后48小时内必须补上3-5条高相关外链。我专门建了个“汽车媒体白名单”,优先投垂直论坛(如汽车之家、懂车帝)的车型对比帖。 -
踩坑:忽视Next.js的301跳转对权重传递的影响
后果:从WordPress迁移时,旧版车型URL(/car/old-model)用next.config.js做了反向代理,结果谷歌把所有旧链接标记为软404。
怎么避免:用redirects()函数设硬性301,加上permanent: true参数。迁移前跑一遍核子GEO的结构化数据检测,卡住所有未匹配的URL。 -
踩坑:用同一套结构化数据模板覆盖所有车系
后果:新能源车和燃油车的参数结构不同(电池容量vs发动机排量),硬套同一个@type:Car导致Google提示“属性冲突”,展示率跌了28%。
怎么避免:按“车型类别”分3套模板(新能源/燃油/混动),每套单独定义additionalProperty,脚本里加个if (carType === 'electric')的分支。 -
踩坑:不监控外链的实时衰减
后果:某次客户换了域名DNS(没通知我),外链指向的旧IP全部失效,两周内反向链接从1200个缩到300个。
怎么避免:在GEO监控里设“外链存活率”警报,低于80%自动短信通知。我每月跑一次核子GEO的全文扫描,把死链批量导出并重定向。 -
踩坑:外链文本锚点只用品牌词
后果:客户要求所有链接锚点写“XX汽车”,结果谷歌检测到98%的链接都是同一锚点,直接判为垃圾外链。
怎么避免:锚点池必须包含长尾词(如“10万级SUV对比”)、车型名(“Model Y参数”)、自然描述(“点击查看续航实测”),比例控制在品牌词40%+长尾词35%+其他25%。