内链到底有没有用?我准备做一次真实实验

内链"有用"这句话被说得太多,但我翻了一圈,能拿出来的证据基本都是经验之谈。所以这次不打算讲道理,直接做一次能复现的实验,把过程和数据都留下来。

实验怎么设计

样本:从本站挑 60 个页面,分成两组各 30 个。挑选条件是——都已经收录、都有非零的展示数、且当前入链少于 3 条。这三条保证两组起点接近,也保证"加内链"是唯一变量。

操作:实验组的每个页面在正文末尾加一个相关页面模块,链向 3 到 5 个语义相邻的页面,锚文本取目标页的 H1。对照组什么都不动。

周期:四周。四周是 Search Console 数据完整落地的下限,短了噪音太大,长了变量控制不住。

观测指标:两组页面的展示数、点击数、平均排名的变化量,以及"已抓取"状态里的最新抓取日期有没有提前。

不做的事也写清楚:这期间不发外链、不改这两组页面的正文、不改 URL。任何一项都会让结果无法归因。

内链到底在改变什么

设计实验的时候要想清楚一件事:内链改变的不是"权重传递"这种模糊的东西,是两个很具体的东西。

一是抓取路径。 一个页面如果从首页出发要 5 跳才能到,爬虫可能一个月才来一次。给它加 3 条来自同层级页面的链接,跳数降到 2,抓取频率会明显上升。这个效果最快能观测到——通常两周内"上次抓取时间"就会有变化。

二是主题聚类。 30 个页面互相链接,形成的是一个关于某个主题的紧密子图。Google 判定的不是单个页面,是这批页面共同覆盖了什么。这解释了为什么在线工具集合站里,同类工具互相链接的那一批通常整体表现更好,而不是单个页面突出。

内链图用数据管,不要手写

60 个页面可以手写,600 个不能。我打算直接把链接关系存进 SQLite

sql
CREATE TABLE pages (
  id INTEGER PRIMARY KEY, slug TEXT, h1 TEXT, category TEXT
);
CREATE TABLE links (
  from_id INTEGER, to_id INTEGER, anchor TEXT
);

构建时查 links 表生成相关页面模块,anchor 默认取目标页的 h1,需要更自然的表达时单独覆盖。

好处有三个:锚文本全站一致,不会出现同一个页面在 A 处叫"利润率计算器"、在 B 处叫"算利润";批量调整某个分类的内链策略只改一条 SQL;能直接统计每个页面的入链数,找出少于 3 条的孤岛页面——这份清单本身就是实验的样本来源。

锚文本只定两条规则

用目标页的 H1 或核心表达,不用"点击这里"。 锚文本是 Google 判断目标页主题的信号之一,写"点击这里"等于主动放弃这个信号。

同一个目标页在不同位置用不同说法。 "利润率计算器"和"怎么算利润率"可以并存,都指向同一页。反过来,几十个页面用完全相同的锚文本指向同一个 URL,是典型的操纵痕迹。

四个要避开的坑

nofollow 不要用在内链上。 内链加 nofollow 等于告诉 Google 这条链接不作数,那你加它干什么。

别做全站页脚链接。 每个页面底部挂 50 个链接,等于每个链接的信号都被稀释到接近 0。底部导航保留分类级链接就够了,语义相关的内链放在正文里。

JS 动态生成的内链要确认能被抓到。React 组件渲染相关页面模块没问题,但必须服务端渲染出真实 <a href>。客户端异步拉取的推荐列表,爬虫看不到,等于没做。

别一次性全站改动。 一次改 3000 个页面的内链,出问题你不知道是哪一批出的问题。分批做,每批之间留观测窗口。

实验结果的判断标准

四周后如果实验组的抓取时间明显提前、而展示数变化不大,说明内链的主要作用确实是抓取而非排名。这个结论本身就很有价值——它意味着内链该优先给那些埋得深的页面加,而不是给已经排在前面的页面加。

如果两组的展示数变化差异在 10% 以内,我会认为内链对排名的直接影响有限,之后把投入重心转到页面本身:一类页面该不该继续生成,参考的就不是内链数量,而是它在 Search Console 里的查询覆盖情况。数据出来之后我会单独写一篇复盘,把原始数字贴出来,包括那些不好看的部分。


实验站点为本 SEO 实验室栏目,观测工具为 Google Search Console 的效果报告与网页报告。