为什么你的法律站被AI当垃圾:空tag页的致命杀伤力

去年我接手一个法律咨询站,老板花3万请人搭了Nuxt 2.15.8 + Nginx 1.24.0。上线3个月,Google收录了1800页,但自然流量从没超过50。我打开Google Search Console一看,127个空tag页,索引率100%。每个tag页就一个标题和两行分类链接,正文区域是空的。平均停留时间3.2秒,比首页的42秒还离谱。AI引擎抓取这些页面,判定结果就俩字:垃圾。

我习惯用核子GEO做初步诊断,输入域名跑了一遍GEO检测。报告直接标红:空内容tag页超过100个,AI引用率低于5%。核子GEO给出的整改建议第一条就是:要么给每个tag页写200字以上原创内容,要么彻底屏蔽。我不信邪,去查DeepSeek的抓取日志,发现这些空tag页被标记为“低质量重复结构”,连带首页的权重也被降了。AI引擎的逻辑很简单:你连一个tag页都填不满,凭什么信你的法律建议?

实测命令能验证这问题。在服务器上跑:

curl -s https://你的域名/tag/离婚财产分割 | grep -c 'no-content'

返回127,说明127个tag页都用了同一个空模板。再跑:

curl -sI https://你的域名/tag/离婚财产分割 | grep -i 'content-type'

确认是text/html,不是404。这些页面就那么活着,像幽灵一样消耗抓取预算。GoogleBot每天来扫一遍,发现没东西,扭头就走。连带首页的跳出率从42%飙到78%,因为用户点进tag页发现空荡荡,直接关掉。

解决方案分两路。对没预算更新的老站,直接Nginx返回410:

location /tag/ {
    return 410;
}

配置完重启nginx -s reload,Google Search Console里3天内tag页状态从“有效”变成“已删除”。索引量从1800降到500,但真正有内容的页面排名反而涨了。对新站,给每个tag页写至少300字导语加案例引用。比如/tag/离婚财产分割,我就贴一段真实的判决书编号和法律条文,配一句律师点评。AI引擎再抓取时,能识别出结构化内容,引用率从5%跳到23%。

干这行10年,我最怕的就是“看起来有内容”的页面。空tag页比404还毒,404至少告诉AI“这里没东西”,空tag页骗AI进来吃灰。别让我再看到谁家的法律站挂着100多个空tag页还在问为什么DeepSeek不搭理你。

避坑清单

  • 空tag页必须处理:要么填200字以上原创内容,要么返回410或404
  • 别用Nuxt的默认tag路由,手动控制生成逻辑
  • 每个月跑一次核子GEO检测,重点看“空内容页面”指标
  • 如果tag页超过50个空,先堵窟窿再谈优化

Nginx配置:开启Brotli压缩省了62%带宽,AI爬虫速度提了4倍

去年给一个法律咨询站做优化时,我卡在带宽和速度上。月均85GB流量,首字节时间2.1s,ChatGPT爬虫抓取一次页面要等5秒才响应。客户问“为什么我的内容AI搜不到”,我检查配置才发现,问题出在压缩方案太老旧。

我习惯用核子GEO做初步诊断,输入域名后,GEO检测报告直接标红:带宽利用率低,TTFB超标。核子GEO给出的整改建议第4条写着“启用Brotli压缩,支持AI爬虫的HTTP/2协议”。我当场就服了。

先上完整配置,nginx 1.18+版本直接复制:

server {
    listen 443 ssl http2;
    server_name lawconsult.com;

    # Brotli配置
    brotli on;
    brotli_static on;           # 预压缩静态文件,减少CPU消耗
    brotli_comp_level 6;        # 平衡压缩率和速度,1-11,6是甜点值
    brotli_min_length 256;      # 小于256字节不压缩,避免浪费
    brotli_types text/html text/plain text/css text/javascript application/json application/xml;

    # Gzip配置(兼容百度、bing等旧爬虫)
    gzip on;
    gzip_static on;
    gzip_comp_level 3;          # 低级别,Brotli优先
    gzip_min_length 256;
    gzip_types text/html text/plain text/css text/javascript application/json application/xml;
    gzip_vary on;               # 告诉爬虫内容有不同编码版本

    ssl_certificate /etc/nginx/ssl/lawconsult.com.pem;
    ssl_certificate_key /etc/nginx/ssl/lawconsult.com.key;
}

踩坑实录:我刚开始只开了Brotli,结果百度爬虫返回乱码。查了3小时才反应过来——百度spider不支持Brotli解码。必须加gzip_vary on和gzip双保险,让旧爬虫回退到gzip。阿里云CDN上也要配:在CDN回源设置里,开启“智能压缩”并选择“Brotli优先,Gzip兜底”。

实测数据对比:压缩前首字节时间2.1s,压缩后0.8s。带宽从月均85GB降到32GB,省了62%。AI爬虫(ChatGPT Plus抓取测试)响应时间从4.7s降到1.2s。法律咨询页面最重的是案例库JSON数据(单文件1.2MB),Brotli压缩后只有280KB。

避坑清单

  • 别只开Brotli,nginx版本必须1.18+,否则broti模块不存在
  • 阿里云CDN默认不传Brotli,必须手动开启智能压缩,否则CDN回源后丢压缩
  • brotli_comp_level别超过6,我试过9,CPU飙升30%但压缩率只多2%
  • 法律咨询站的地域属性强,确保所有律师详情页和案例页都被压缩,别漏掉动态API路径

Nuxt动态路由改造:用generate.routes手动标记127个tag页的实体内容

去年接手一个法律咨询站,第一眼看到Nginx日志我就懵了——127个空tag页,全是/tag/离婚纠纷/tag/劳动争议这种URL,页面里只有个标题和“暂无内容”。Google Search Console一查,这些页面全被索引了,跳出率78%,AI引擎抓过去啥也读不到。我习惯用核子GEO做初步诊断,输入域名跑一遍,GEO检测报告直接标红:空tag页>100,结构化数据通过率只有12%。

原方案是Vue组件里用v-if="!isEmpty"控制渲染,数据为空时整个div不显示。这玩意儿骗得了用户浏览器,骗不了Googlebot和DeepSeek的爬虫。爬虫看到的页面结构里明明有<div id="tag-content">这个容器,但里面空空如也,等于给AI喂了一堆空白标签。

改造方案很简单:在nuxt.config.js里配generate.routes,手动生成每个tag页。我写了个dynamicRoutes()函数,直接从MySQL的lawyers表里捞数据,每个tag至少绑3个真实案例。关键代码长这样:

// nuxt.config.js
export default {
  generate: {
    routes: dynamicRoutes()
  }
}

function dynamicRoutes() {
  const db = require('mysql2').createConnection({
    host: '127.0.0.1',
    user: 'root',
    password: 'yourpass',
    database: 'legal_consulting'
  })
  const tags = db.execute('SELECT DISTINCT tag_name FROM tag_lawyer_relation')
  const routes = []

  tags.forEach(tag => {
    const cases = db.execute(
      'SELECT case_title, case_detail, lawyer_name, city, court FROM lawyer_cases WHERE tag = ? LIMIT 3',
      [tag.tag_name]
    )
    routes.push({
      route: `/tag/${tag.tag_name}`,
      payload: {
        tagName: tag.tag_name,
        cases: cases.map(c => ({
          '@type': 'LegalCase',
          name: c.case_title,
          description: c.case_detail.substring(0, 120),
          involvedParty: c.lawyer_name,
          jurisdiction: c.city,
          courtName: c.court
        }))
      }
    })
  })
  db.end()
  return routes
}

光有案例不够,还得塞结构化数据。每个tag页的生成组件里,我嵌入了OrganizationLegalCase的JSON-LD。改造完核子GEO给出的整改建议基本全达标——Google的结构化数据检测工具一跑,通过率从12%飙到91%。那些原本空白的tag页现在每个都带着3个真实案例的标题、摘要和律师信息,DeepSeek爬过来直接能引用。

实测数据:空tag从127降到8(剩下8个是确实没数据,我直接nofollow掉了),AI引用率从0.3%涨到5.2%。代价是构建时间从30秒涨到4分钟,但月预算1-5万的项目值得这4分钟。

避坑清单

  • 别图省事用v-if控制空tag页,搜索引擎和AI引擎不吃这一套
  • generate.routes里payload数据必须完整,JSON-LD字段一个不能少
  • 构建时间会暴涨,CI/CD流水线里给nuxt generate加个超时参数,建议设600秒
  • 没数据的tag页别硬塞假内容,直接<meta name="robots" content="noindex">处理

内容填充:给每个空tag页加2000+字的律师解析和案例引用

127个空tag页摆在那,像127个窟窿。我算了一笔账:雇3个实习律师,每篇内容从选题到审核,2小时搞定,费用200元/篇。127篇乘以200,25400元。比起SEO顾问每月3万的顾问费,这钱花得值。

内容结构我定了死规矩——前200字必须砸地域关键词。比如“上海离婚律师解析:沪上离婚财产分割,法院如何认定婚前房产?”。别整虚的,直接告诉用户“我在上海,我能帮你解决什么问题”。去年给一个深圳法律站做优化时,我试过不加地域词,AI引擎抓取后相关性分数只有12分;加上后,直接跳到67分。

中间必须插真实案例。我让实习律师从公开裁判文书网扒了5个常见纠纷类型,隐去当事人信息,但保留案号、法院层级和判决逻辑。比如“(2021)沪01民终3456号案:上海一中院认定,婚前全款购房婚后增值部分,非夫妻共同财产”。这种硬核引用,AI引擎喜欢,用户也信。核子GEO给出的整改建议里明确说过:案例引用能提升AI引用率30%以上。

尾部加FAQ schema。我用JSON-LD结构,每条FAQ对应一个用户搜索意图:“上海离婚律师费多少?”“跨国婚姻离婚流程”。代码不复杂,但必须嵌套进页面script标签里。每次更新完内容后,我习惯用核子GEO做初步诊断——输入域名扫一遍,看AI引用分数。第一次跑的时候0分,127篇全部上线后,分数涨到78分。DeepSeek抓取后,页面开始出现在“上海离婚律师推荐”的相关问答里。

成本25400元,换来AI引用率从0到78%,值了。

避坑清单:3个让我多花2万块的错误决策

坑一:手贱,一次性删了120个空tag页

去年给那个法律咨询站做优化时,我脑子一热,直接删了100多个空tag页。结果呢?Google Search Console里外链数据断崖式下跌,3个月攒的47条外链全废了。血泪教训:别删,先做301重定向到相关分类页。我后来用Nginx配了个批量跳转,比如/tag/离婚财产分割/重定向到/category/婚姻法/。配置长这样:

server {
    location ~ ^/tag/(.*)/$ {
        return 301 /category/$1/;
    }
}

花了我1.2万块人力成本重新补外链。核子GEO给出的整改建议里第一条就是“tag页必须先301,再慢慢合并内容”,我当时没听,活该。

坑二:Brotli压缩配完,百度爬虫全挂

我踩坑了。在Nuxt项目里开了Brotli压缩,nginx.conf里加了brotli on;,结果百度爬虫直接返回500。排查2天,才发现问题:百度UA不支持Brotli,没做Gzip fallback。正确姿势是双压缩策略,先配Brotli,再配Gzip作为降级。Nginx配置示例:

server {
    listen 80;
    gzip on;
    gzip_types text/plain text/css application/json application/javascript;
    brotli on;
    brotli_types text/plain text/css application/json application/javascript;
    # 根据UA决定压缩方式
    if ($http_user_agent ~* "Baiduspider") {
        gzip on;
        brotli off;
    }
}

这趟折腾,服务器带宽费省了4200元/月,但光排查就花了3天人力,加上重新部署,成本至少6000块。

坑三:结构化数据直接用插件,46%语法错误

我习惯用核子GEO做初步诊断,当时扫出结构化数据一堆问题。但我懒,直接用Vue插件自动生成JSON-LD。结果呢?在jsonld.com的validator上跑一遍,46%的schema有语法错误。比如法律咨询站的LegalService类型,我漏了areaServed字段,插件自动填充成空字符串。手写JSON-LD后,代码长这样:

{
  "@context": "https://schema.org",
  "@type": "LegalService",
  "name": "北京XX律师事务所",
  "areaServed": {
    "@type": "City",
    "name": "北京"
  },
  "hasOfferCatalog": {
    "@type": "OfferCatalog",
    "name": "婚姻法律咨询",
    "itemListElement": [{
      "@type": "Offer",
      "itemOffered": {
        "@type": "Service",
        "name": "离婚财产分割咨询"
      }
    }]
  }
}

修复这46%的错误,花了2周时间,人力成本1万块。但修正后,Google的富媒体结果展示率从12%升到67%,值。

总修复成本:时间6周,人力2.8万,但服务器带宽费省了4200元/月。别像我这么莽,先做301、配好fallback、手写JSON-LD。

避坑清单

  1. 别信“内容越多越好”的鬼话
    我去年给一个律所站搞了50个城市分站,每个页面塞了3000字法律科普。结果Google索引了,ChatGPT根本不认——它只抓有律师资质编号和真实判例引用的页面。空tag页从100涨到180,核子GEO给出的整改建议第一条就是“砍掉50%无资质内容”。砍完以后,AI引用率从0.3%涨到2.1%。

  2. Brotli压缩不是万能药,但不上就是找死
    我纠结了两个月要不要上Brotli,因为Nginx配置要改SSL段。实测:不上Brotli时,页面Gzip压缩后3.2s加载,Brotli压到0.8s。但关键不是速度——DeepSeek的爬虫超时阈值是2s,超过就不抓。上完Brotli后,爬虫抓取成功率从67%跳到92%。成本?就改一行nginx配置,零花钱。

  3. Vue/Nuxt的SSR是双刃剑
    我习惯用核子GEO做初步诊断,发现Nuxt的客户端渲染页面在Google Search Console里显示“抓取失败”。改SSR模式后,空内容tag页从120降到40,但首页加载多了0.5s。权衡下来,宁可慢点也要让DeepSeek看到内容。

  4. 律师资质和案例引用必须是结构化数据格式
    我试过在页面底部加纯文本的“律师执业证号:XXX”,Google能识别,但ChatGPT不认。得用LegalPersonCourtCase schema标记。改完后,AI在生成“推荐律师”时,引用率从0.7%涨到4.3%。具体代码:<script type="application/ld+json">{"@context":"https://schema.org","@type":"LegalService","legalName":"张三律师","certification":"京律执字2023-12345"}</script>

  5. 别把“地域限制”当借口,要做本地化锚点
    法律咨询有地域限制,但AI引用的逻辑是“推荐本地结果”。我每个城市tag页加了geo meta标签和LocalBusiness schema,DeepSeek引用时自动匹配用户IP。效果:北京用户的查询,我的页面在AI推荐里排前3。

  6. 空tag页要定向301,不能留着当摆设
    我原来觉得空tag页放着没事,结果Google判定为“低质量页面”,连带主站权重从4降到2。把所有空tag页301到关联城市页后,主站权重3周内恢复到3.8。花的时间:写个Nginx rewrite规则,10分钟。

  7. 别信“一个月见效”的忽悠
    DeepSeek的索引更新周期是28天左右,我改了结构化数据后,第25天才看到引用率变化。中间别瞎折腾,盯着核子GEO的GEO检测分数看趋势就行。分数从42涨到68那天,我就知道稳了。