# 程序化SEO最容易踩的坑是什么？

URL: https://caijiao.org/posts/162
Source: docs/posts/162.md
Description: Omni 的 /other/test-grade 主词 5900 搜索量，页面月访问 61086；/finance/annual-income 主词 81000，页面只有 50825。用主词搜索量排优先级，是最早会踩的坑。

Omni Calculator 有两个页面适合放在一起看。/other/test-grade 的主关键词月搜索量 5900，这个页面每月拿到 61086 次访问；/finance/annual-income 的主词搜索量 81000，是前者的十几倍，页面月访问 50825，反而更少。

![Omni Calculator 官网首页截图](/images/2026-09/omnicalculator.com.png)

*Omni Calculator 首页还有一个 Discover Omni 板块，自我介绍是「用计算揭示世界的惊人真相」。*

按主词搜索量排优先级，这两个页面的顺序会排反。这是程序化 SEO 里最早会踩、也最难自己察觉的坑：**你拿来做决策的那个数字，和页面真实价值之间几乎没有相关性。**

## 主词搜索量预测不了页面流量，因为页面吃的从来不是主词

61086 减去 5900，剩下的五万多访问来自哪？来自"成绩计算器"这个词的所有变体：按学分算、按权重算、期末要考多少分才能过、加权平均分怎么算。这些查询每一个单独看都不大，加在一起才是页面的真实体量。

反过来，annual-income 这个词虽然大，但它后面的长尾很短——用户搜的就是"年收入计算器"，不太会去搜"年收入计算器 按双周发薪"。主词大、长尾薄，总量就被反超了。

所以评估一个模板该不该铺开，看的不是它主词多亮眼，是这个词族能不能自然长出几十个不同的具体查询。

具体怎么估：把这个核心词放进关键词工具，看它下面挂了多少个相关的真实例子，再看这些例子的搜索意图是不是一致。能稳定长出三十个以上变体、且变体之间只是参数不同的，模板值得铺；只有三五个变体、其余都要靠造句凑的，铺出来就是空页面。

另一个更省事的验证法是看已有站点的表现。/finance/salary-to-hourly 主词 42000、页面 45940，/finance/margin 主词 55000、页面 49169——这几个页面都落在 1 比 1 附近，说明"时薪换算""利润率"这类词族的长尾厚度差不多。摸清自己品类的这个比例，比逐个词去查快得多。

## 参数自由组合，是最快的翻车方式

第二个坑紧接着第一个来。既然"组合越多越好"，那就把币种 × 单位 × 场景 × 年份全排列一遍，一个模板能瞬间吐出几千个 URL。

问题在于，绝大部分组合在真实世界里没有对应查询。"把 2019 年的日元换算成英寸"这种页面，语法正确、数据正确、没人搜。它们进不了索引，或者进了索引也零访问，最后变成 Search Console 里那一长串"已抓取，但未索引"。

Google 对这件事有专门的说法，Scaled Content Abuse（4.6.5）针对的就是大量低投入、低原创性、没有经过编辑判断的内容。判定不看你是手写还是程序生成，看这批页面各自有没有独立存在的理由。

一个能立刻用的筛选规则：生成之前，对每个组合问一句"会不会有人用这个具体组合去搜"。答不上来的组合就不生成。宁可先做 300 页全是有效页面，也别做 3000 页里只有 300 页有用——前者的收录率是 100%，后者的收录率会拉低整批站点的索引质量判断。

## 客户端渲染出来的页面，爬虫拿到的是空壳

第三个坑更技术一些。10015.io 是个很典型的例子：Next.js 加 styled-components，50 多个工具，几乎所有计算都在浏览器里跑，AdSense 月收入约 300 美元。架构上没问题，体验和成本都划算。

但工具页面如果整个靠前端路由渲染，服务端返回的 HTML 里没有标题、没有说明、没有示例值，爬虫看到的是一个等着 JS 执行的空容器。等它执行完，这一轮抓取可能已经结束了。用 [JavaScript](/javascript/) 做交互完全没问题，前提是页面的 HTML 骨架在服务端就已经生成好。

速度是同一件事的另一面。Omni 的广告负责人 Alexander Utz 说过，页面速度对他们没有商量余地，整个增长都依赖 SEO，Core Web Vitals 直接影响排名。这句话成立的前提，是页面先被完整索引了。

重的计算放在浏览器里其实有现成方案，用 [WebAssembly](/webassembly/) 把编解码和数值计算编译成 wasm，客户端跑，服务端只发静态文件。这样既保住了交互速度，也不必把每次计算都做成需要等待的服务端请求。

## 内链没有跟着页面一起生成，几千页就是几千个孤岛

程序化最容易漏掉的是这一层：页面生成脚本写完了，模板套好了，sitemap 也输出了，但页面之间没有任何链接关系。搜索引擎只能靠 sitemap 发现它们，权重也没有传递路径。

修法是在模板里留一个"相关工具"模块，按同一父目录下的邻近条目自动取 5 到 8 个。取的时候不要随机，按相关性排序——同一个输入类型的排前面（PNG 相关页面互链），跨类别的只在页面底部放一次。这样每次新增页面，内链是自动长出来的，不需要人工维护一张链接表。

新页面还应该有反向入口：首页或类别页上保留最近新增的条目列表，让新页面在发布当天就有至少一条站内路径可达。这一块和 [sitemap 与 robots 的配置](/google-search-central/04-sitemaps-robots)是配套的：sitemap 负责让页面被找到，内链负责让页面被理解。几千页的站点，sitemap 要分片，分片边界最好和目录结构一致，这样哪一批没收录一眼能看出来。

页面上的结构化数据同理，应该在模板里和标题用同一套变量一起注入，而不是事后补，写法照通用的 JSON-LD 实现即可。

先别问"能不能生成几千页"，先问"这一批里有多少页能各自拿到至少一个真实查询"。答不上来，量铺得越大，清理的成本越高。

---

*Omni Calculator 单页数据来自 Ahrefs（2026 年 6 月）；Alexander Utz 表述引自公开访谈；10015.io 技术栈与收入数据来自作者在 Indie Hackers 的公开分享。*
