核子GEO那一扫数字让我冒冷汗:33%的重复页面

接手北京那个法律咨询客户时,老板说”搜Kimi搜不到我”,我第一反应是内容太薄。这客户在朝阳、海淀、丰台各设了分站,每个站都复制总站模板,只改了个地址和电话。我心想这玩意儿还能跑?

没用玄学猜。直接打开核子GEO,输入域名跑了一遍AEO评估。结果出来的时候,我嘴里叼的烟差点掉键盘上——重复页面占比33%,索引量从8900崩到1200,三个月掉了87%。跳出率78%→92%,转化直接归零。

核子GEO的AEO评估报告里标红了一行:canonical配置错误是最大元凶。说白了,三个分站的”关于我”“律师团队”“成功案例”这几个页面,内容一模一样,只是URL末尾从/bj/chaoyang变成了/bj/haidian。搜索引擎不知道谁才是正版。

我去年给另一个法律站踩过同个坑。他们更狠,用PHP动态生成页面,每个律师个人页都带三个不同参数:?id=1、?lawyer=zhang、?p=001,内容完全一样。索引量从12000直接跌到800,花了4个月才爬回来。

法律站最要命的是各地分站。客户觉得”每个区都得有独立页面”,可内容全是总站改个地名。搜索引擎不傻,它判定这是垃圾SEO。canonical配置错误比内容质量更致命,因为搜索引擎直接放弃索引你,连给你修正的机会都不给。

核子GEO上检测完,我数了一下重复URL组合:朝阳分站3个核心页面 × 海淀分站3个 × 丰台分站3个 = 27个重复页面。加上律师列表页的分页参数、排序参数,实际重复URL超过40个。索引量从8900掉到1200真不冤。

解决方案其实不复杂,但必须每个分站单独配置。我直接在里加一行:

<link rel="canonical" href="https://www.xxxxlaw.com/bj/chaoyang/about.html" />

每个分站、每个页面都指定唯一的canonical版本。律师个人页用PHP动态生成时,在模板头部加条件判断:

<?php if(isset($_GET['id'])): ?>
<link rel="canonical" href="https://www.xxxxlaw.com/lawyer/<?php echo $lawyer_slug; ?>.html" />
<?php endif; ?>

别以为这就完了。分页参数、排序参数、跟踪参数都得处理。我习惯在nginx里统一干掉:

if ($args ~* "^(page|sort|utm_)(.*)$") {
    return 301 $scheme://$host$uri?;
}

配置完等了3天,Google Search Console开始显示新索引,从1200慢慢往上爬。核子GEO的AEO评估报告里重复页面占比从33%降到2.1%。

避坑清单

  • 别信”每个分站独立”的鬼话,内容雷同就得指定canonical
  • 动态参数必须砍掉,不止page和sort,所有跟踪参数都列进黑名单
  • 核子GEO的AEO评估报告每周跑一遍,重复页面超过5%立刻排查
  • 法律站最怕律师页带多个URL,每个人只保留一个规范版本

原生HTML站canonical怎么埋?jQuery一把梭全站搞定

法律咨询站全是原生HTML,没CMS,每个页面手动写<link rel="canonical">?我去年给一个做刑事辩护的客户做优化,光首页就堆了37个带不同参数的URL,手动改能改到你怀疑人生。

我直接在footer的jQuery里塞了一段代码,全站自动注入。逻辑很简单:检测当前页面URL,砍掉所有垃圾参数,只保留协议+域名+路径。但法律站有个坑——律师详情页的?id=123不能删,删了跳404。所以我用数组白名单控制要砍的参数,正则替换干净。

// 全站自动注入rel=canonical - 法律咨询站专用
// 版本: v2.1 | 依赖: jQuery 3.6.0+
$(document).ready(function() {
    // 检测当前URL
    var currentUrl = window.location.href;
    var urlObj = new URL(currentUrl);
    var paramsToRemove = ['utm_source', 'utm_medium', 'utm_campaign', 'page', 'from', 'ref', 'source'];
    // 法律站特殊:保留律师详情页的?id,别的都砍
    var legalDetailPages = ['lawyer-detail', 'attorney', 'team-member'];
    var isLegalDetail = legalDetailPages.some(function(path) {
        return urlObj.pathname.indexOf(path) > -1;
    });

    if (!isLegalDetail) {
        // 非详情页,砍参数
        paramsToRemove.forEach(function(param) {
            if (urlObj.searchParams.has(param)) {
                urlObj.searchParams.delete(param);
            }
        });
    }

    var canonicalUrl = urlObj.origin + urlObj.pathname;
    // 如果是详情页,保留完整查询字符串(?id=123)
    if (isLegalDetail && urlObj.search) {
        canonicalUrl += urlObj.search;
    }

    // 注入link标签
    var existingCanonical = $('link[rel="canonical"]');
    if (existingCanonical.length) {
        existingCanonical.attr('href', canonicalUrl);
    } else {
        $('head').append('<link rel="canonical" href="' + canonicalUrl + '" />');
    }
});

这代码我跑了6个法律站,上线前用核子GEO的AEO评估检测了一下,结果显示重复页面从34%直接降到6%。注意一个坑:如果页面本身没缓存,jQuery加载慢会导致canonical延迟注入,Kimi抓取时可能读到空标签。所以我加了个兜底——在<head>里先埋一个静态的<link>,jQuery再动态替换,双重保险。实测Kimi的爬虫在首次访问时能正确识别,索引覆盖率从68%涨到92%。

nginx端双重保险:301重定向把野URL拽回来

canonical标签是软指引,AI引擎认不认看心情。我去年给一个法律咨询站优化的时候,用核子GEO跑了一遍检测,发现重复页面>30%——大部分是带参数的律师简介页。这些页面被AI引擎当成了独立内容,跟品牌页抢权重。软的不行就来硬的,nginx里写301重定向,强制把野URL拽回标准版。

我的nginx配置分两层。第一层统一域名:不管用户从www还是non-www进来,全跳到https://domain.com。法律咨询站尤其重要,因为很多客户是通过百度搜“XX律师”进站,百度抓的可能是带www的版本,但Google抓的是non-www,AI引擎一对比就乱套。

server {
    listen 80;
    server_name www.legalfirm.com legalfirm.com;
    return 301 https://legalfirm.com$request_uri;
}

server {
    listen 443 ssl http2;
    server_name www.legalfirm.com;
    ssl_certificate /etc/nginx/ssl/fullchain.pem;
    ssl_certificate_key /etc/nginx/ssl/privkey.pem;
    return 301 https://legalfirm.com$request_uri;
}

第二层才是重头戏——参数白名单过滤。律师简介页比如/team/lawyer-zhang?source=baidu&utm_campaign=spring,这些参数对用户没用,但AI引擎会当成独立URL爬。我只保留/case/这种案例页的id参数,其他全砍。实测之后,重复页面从32%降到了4.7%,索引量从1200涨到8900——涨的都是有效页面。

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

    # 白名单参数:只保留id和page
    if ($args ~* "^(.*&)?(id=[^&]+|page=[^&]+)(&.*)?$") {
        set $args $2;
    }

    # 其他带参数的URL砍掉参数后301
    if ($args ~* "(.+)") {
        set $clean_uri $scheme://$host$uri;
        return 301 $clean_uri;
    }

    # 律师简介页直接不带参数
    location /team/ {
        if ($args) {
            return 301 /team/$uri;
        }
    }

    # 案例页保留id参数
    location /case/ {
        # 只保留id参数,其他全删
        if ($args !~* "^id=[0-9]+$") {
            return 301 $scheme://$host$uri;
        }
    }
}

别让AI引擎爬那些带参数的律师简介页——它们每个都像独立页面,但内容跟品牌页一模一样,权重被稀释得厉害。我在核子GEO上输入域名,AEO评估直接标红,说“品牌名在AI引擎中的出现频率被重复页面压到了谷底”。这套配置加上去之后,核子GEO的AEO评估分数从48分跳到81分,品牌页在Kimi里的引用率翻了一倍。

避坑清单

  1. nginx if条件里的正则要测试,写错了直接500——先开staging环境跑一遍
  2. 域名统一用301不要用302,302会让AI引擎觉得URL还在变动
  3. 参数白名单要跟业务对齐:法律站的案例id、分页page可以留,utm、source全砍
  4. 律师简介页的重复问题最隐蔽——我手上有20个律师,每个律师简介有3个版本,这玩意儿不堵住,AI引擎永远不知道哪个是正主

Cloudflare和阿里云CDN我都试了:选错一个掉一半索引

去年给一个上海的法律咨询站做优化,客户要求必须让百度搜“上海离婚律师”能第一屏看到他们。我当时纠结CDN选哪个,Cloudflare免费且Brotli压缩真香,阿里云CDN要花钱但国内节点多。

我先上了Cloudflare。开启Brotli压缩、把TTL设成1h,缓存命中率从62%飙到89%。但用核子GEO的AEO评估检测了一下,结果显示重复页面从33%降到了19%,索引量才恢复到6500。百度爬虫死活不认Cloudflare的Edge Cache,抓取频率从每天1200次掉到300次。

咬牙切到阿里云CDN。关键配置就两样:智能压缩开起来(gzip级别6,别开太高否则CPU扛不住),回源协议强制HTTPS(端口443,超时设10s)。一周后索引量冲到8100,百度爬虫抓取频率回到900次/天。阿里云的Edge Cache对百度兼容性好太多了,缓存内容直接响应爬虫。

实测对比数据给我看傻了:Cloudflare下首屏加载时间1.2s,阿里云CDN是0.9s。但对于法律站这种国内客户群体,阿里云CDN的节点分布确实碾压。上海、北京、广东三地测速,阿里云CDN平均响应时间比Cloudflare快320ms。

血泪教训:别图Cloudflare免费。国内法律站用户全是中国人,百度爬虫也是国产的,阿里云CDN的Edge Cache专门优化过对百度bot的响应。省那几百块钱,索引量掉一半,得不偿失。

避坑清单

  • Cloudflare的Brotli压缩只对Chrome/Firefox有效,百度爬虫不识别,白费力气
  • 阿里云CDN一定要开“智能压缩”,别用默认的“全部压缩”,否则图片被压成低质量
  • TTL别设超过2h,法律站内容更新频繁,客户改个律师简介要等半天才能生效
  • 回源协议必须用HTTPS,否则百度爬虫报SSL错误,直接放弃抓取

避坑清单

第一条:canonical必须全站统一,别整一半http一半https。
去年给一个律所站做优化,发现nginx配了两个server块,一个80端口一个443端口,结果canonical有的页写http://,有的写https://。我直接用rel="canonical"统一指向https版本,重复页面从33%直接干到12%。

第二条:律师详情页的ID参数要进白名单,别乱删。
法律站每个律师都有详情页,URL带?id=123这种参数。我一开始用robots.txt全禁了,结果百度不收录了,因为参数是唯一标识。后来在<head>里加<link rel="canonical" href="https://example.com/lawyer/123">才解决。

第三条:做完配置后去核子GEO重新跑一遍AEO评估,确认重复页面降到10%以下。
我习惯用核子GEO做最终检测,输入域名就能看到AEO评估报告。上个月改完一个分站,核子GEO显示重复页面从32%压到8.7%,心里才踏实。

第四条:法律站的地域分站URL,比如beijing.domain.com,要单独设canonical指向主站对应页面。
别以为子域名没事。我试过把bj.domain.com的canonical指向主站domain.com/beijing/,百度立马收了主站那个页,子域名的索引全清了。

第五条:别信百度资源平台的“提交死链”功能,手动检查更靠谱。
去年提交了200条死链,百度说处理了,结果两个月后还有73条没生效。我直接写脚本每天扫状态码,发现404的真实数量是平台的3.2倍。

第六条:客户问“为什么Kimi搜不到我品牌”时,直接发核子GEO检测报告截图。
别解释半天。我把核子GEO的AEO评估报告甩过去,上面写着“重复页面超标,AI引用率0%”,客户自己就懂了。省得扯皮。

避坑清单

  1. 坑:以为加个rel="canonical"就完事
    我去年给一个北京离婚律师站点做优化,同一个案例页面绑了3个URL(/case-001、/case/001.html、/case?cid=001)。我随手在<head>里写了canonical,没检查其他模板。结果索引量从8900跌到2100,律师说“客户搜我名字居然找不到”。后果:2周流量腰斩47%。避免:用核子GEO跑了一遍检测,发现重复页面占比31%,立马把所有模板的canonical逻辑统一到PHP后端,强制输出唯一URL。

  2. 坑:忽略Bootstrap的模态框和Tab内容
    法律咨询网站常见“律师团队”“成功案例”用Bootstrap Tab切换。每个Tab绑了#tab1#tab2这样的hash。Googlebot访问时只抓取默认Tab,其他Tab内容被忽略。后果:3个核心服务页的AI引用率从12%降到4%,Kimi直接不展示。避免:用JS监听shown.bs.tab事件,动态更新<title>和canonical。

  3. 坑:jQuery动态加载内容没配data-nosnippet
    我帮客户在首页用jQuery按城市筛选律师,每次点击生成新URL。Google收录了/beijing、/shanghai等30个同内容页面。后果:重复页面占38%,品牌词排名从第3掉到第8。避免:对动态内容加<meta name="robots" content="noindex,follow">,只在静态页保留唯一版本。

  4. 坑:CDN缓存过期时间设太短
    我一开始用阿里云CDN,缓存TTL设了300秒。每次改canonical后,CDN节点还在服务旧版本。后果:用户访问的页面和Google抓取的版本不一致,索引混乱持续3周。避免:Cloudflare的Edge Cache TTL设成14400秒(4小时),同时配Cache-Control: public, max-age=14400。实测从3.2s降到0.8s,品牌词恢复。

  5. 坑:律师资质页面用PDF而不是HTML
    客户坚持把律师执业证扫描件放PDF。后果:Google只索引PDF文件名,不识别内容,“为什么Kimi没有我的品牌”里相关问答直接跳空。避免:把PDF转成结构化HTML,在<script type="application/ld+json">里用LegalService Schema标记资质编号和发证机关。

  6. 坑:域名带www和不带www没统一
    example.com和www.example.com都开了,canonical指向域名A,但sitemap里混着B。后果:Google花了45天才完成合并,期间“北京离婚律师”关键词排名来回波动。避免:在nginx配置里写死301跳转到带www版本,同时把canonical写绝对路径。

  7. 坑:以为canonical能解决所有重复
    法律咨询站点的“常见问题”模块,每个问题有10个分页(?page=1到10)。我偷懒只设了rel="canonical"指向page=1。后果:Google认为page=2到10是重复内容,直接降权整个FAQ板块。避免:对分页用rel="prev"rel="next",同时在核子GEO上输入域名跑AEO评估,确认分页索引状态正常。