工程日记・第二十四天:冲刺 10K 索引 ——4 波改造、2,433 新 URL、Hub 链接重构
起点:8,000 索引,目标 10,000
今天开始时目标很清晰:把 Google 索引页面从 8,000 拉回 10,000+。几周前峰值是 9,200——掉下来不是惩罚,只是发现延迟加上几个技术问题积累的结果。
诊断花了 30 分钟,过了两个 GSC 导出包和一次 sitemap 审计。根因:
- 6,336 个页面"已发现——当前未索引"(占未索引的 76%)。Google 自然爬虫积压,随站点质量稳定会自愈。
- 726 个页面 hreflang/canonical 错配,验证中。
- 203 个被 robots.txt 错误拦截,验证移除中。
- 40 个locale 重复路径(
/ja/ja/、/pt/pt/...),中间件已 301 重定向。 - 1 个致命遗漏:Industry Insights 模块(103 条洞察 × 11 语言 ≈ 1,133 页)两周前已部署,但从未加入 sitemap.ts。页面存在,但 Google 不知道它们存在。
把诊断转成四波计划,当天全部上线。
第一波 —— Sitemap 修复 + GEO 同步(+121 URL,约 1,331 hreflang 候选)
当天 ROI 最高的单一动作就是 sitemap.ts 30 行新增:一个 getAllInsightSlugs() 循环 + type/daily/weekly 聚合。一次提交 121 个新 URL。
GEO(生成引擎优化,让 ChatGPT/Claude/Perplexity 能引用)层面,扩展 generate-llms-full.ts 构建脚本,加入完整 Industry Insights 索引表:103 条带日期、类型、置信度、实体、URL。重生成的 llms-full.txt 1,523 行 / 127 KB。
IndexNow 已有 industry-insights 类别(之前 commit 加的)。部署后数分钟内向 Bing/Yandex/Naver/Seznam 推完了 121 URL。
第二波 A —— 运营商 × 飞机配对页(+1,798)
接下来一个问题:我们有 54 个运营商和 161 架飞机,能否在不产生薄页的前提下生成有意义的两两配对页?全笛卡尔积是 8,694——绝大多数会被 Google 当垃圾处理。
答案是 operator-aircraft-match.ts 里的双层匹配:
- 第一层 —— "Operates":运营商的
fleetTypes数组与飞机名 fuzzy 匹配。强事实信号。406 页,不设上限。 - 第二层 —— "Compatible":飞机类别与运营商现有机队类别重合。每运营商按
max(12, min(30, opCategories.size × 12))上限取 top,按制造商匹配 + 详细页面丰度评分。1,392 页。
合计 1,798 个高质量配对页,路由 /insights/operators/[slug]/aircraft/[aircraftSlug]。每页含 5 级面包屑、FAQPage 富结果、tier 配色徽章(Operates 绿色,Compatible 冰蓝)、按运营商类型加权的价格区间、飞机规格表。
我们刻意没有复用 EntityPageShell——那个组件是为单实体 + 3 级面包屑设计的。配对页本质是双实体,所以直接拼装 sub-components(MetricCard、InsightSection、CoBrandingBadge)。少一层抽象,对数据更诚实。
第二波 B —— 空腿 × 机型类别成本页(+223)
基础 /empty-legs/[slug] 页展示一条航线 commonAircraft 混合的整体价。但搜索意图"[城市对] 空腿 [light/midsize/heavy/ultra] 机型——多少钱?"没被直接回答。
empty-leg-cost-match.ts 取 62 路线 × 4 类别,按航程过滤掉不可行组合(light jet 飞不动 3,300 海里的新加坡-悉尼空腿),计算:
- 标准包机价 = 类别每小时市价 × 飞行时间
- 空腿价 = 标准价 × 30–55% 折扣区间
- 按类别典型容量(light=6、mid=8、heavy=12、ultra=14)算的人均价
- 该类别中能真正飞这条航线的 top 3 机型
- "fit note" 明确告诉用户某类别在该航线上是过剩配置(重型机飞 1,000 海里短途)还是不足——不制造虚假信心
结果 223 页,路由 /empty-legs/[slug]/[category],category ∈ {light-jet, midsize-jet, heavy-jet, ultra-long-range}。URL slug 故意冗长,因为"light jet empty leg cost"是真实的长尾搜索词,理应出现在 URL 中。
第二波 C —— 机场 + 飞机 FAQ 实体页(+249)
Search Console 数据显示大量未被回答的搜索意图:"Teterboro 有哪些 FBO"、"Phenom 300 包机多少钱一小时"。数据我们都有——跑道长度、FBO 数量、每小时费率、航程——但没有专门的 FAQ 页配 FAQPage JSON-LD。
两个新生成器:
- airport-faq.ts——每个机场 7 个问答:ICAO/IATA 代码、跑道长度与机型类别准入(含跑道→类别启发式)、FBO 列表 + 服务摘要、海关可用性、24/7 运营、热门航线、附近景点。全部从
FeaturedAirport+getFBOsByAirport数据派生。 - aircraft-faq.ts——每架飞机 7 个问答:每小时费率 × 5 小时行程价、按航程区间举的真实路线例子、客舱规格、哪些运营商飞此机型(复用第二波 A 的
getAircraftOperatorMatches)、同类相似机型、制造商 + 速度、预订流程。
第二波 A 解锁了第二波 C:飞机 FAQ 的"Which operators fly the Global 7500?"问题答案直接来自配对匹配数据——"NetJets、Flexjet、VistaJet、XO 和 Global Jet Capital,外加另外 12 家"——不是凭空造的列表。
第三波 —— GEO 护城河:Person、NewsArticle、SpecialOffer(+12 URL,285 页 schema 升级)
第三波的页面增量小(12 个新 URL)。Schema 升级影响很大。
从 blog/posts*.ts grep 出 6 个独特作者:VOLO Editorial、CTO、Engineering、Aviation、Strategy、Leadership。不是 84 个个人 persona——6 个团队实体,诚实,避免造假。
每位:
/about/authors/[slug]—— Person schema 档案页,含jobTitle、worksFor、knowsAbout、sameAs。稳定的@idURL 让其他 schema 能引用此 Person。/blog/by/[author]—— CollectionPage + ItemList schema 归档页,含此作者全部文章。
博客详情页拿到一次低调但深远的升级:内联 articleJsonLd 对象被 <NewsArticleJsonLd> 组件替换。@type 从 ["Article", "BlogPosting"] 升级为 ["NewsArticle", "BlogPosting"]——获得 Google News Top Stories 入选资格。author 通过 getAuthorByName(post.author) 解析为真实 Person,author.@id 链向 /about/authors/[slug]。这才是搜索算法真正在找的 E-E-A-T 信号。
空腿页拿到 SpecialOfferJsonLd:含 priceSpecification、LimitedAvailability 和嵌入 eligibleTransactionVolume 的标准包机参考价(schema.org 的 Offer 类型没有一等的"% off"字段)。62 个父页 + 223 个类别子页 = 285 个新 Offer 资格 URL。
内部链接 —— 4 个 Hub 向下到 ~2,400 个子页
给 sitemap 加 URL 不会自动产生链接权重。这 2,400 个新子页只有面包屑作为入站链接。下一关:每个 hub 页都要展示其子页。
| Hub | 展示 | 形式 |
|---|---|---|
/insights/operators/[slug] | up to 8 张 "Aircraft Operated" 卡 | 3 列网格、tier 配色徽章 |
/empty-legs/[slug] | 1-4 张 "Browse by Aircraft Category" 卡 | 4 列网格、FAQ 之前 |
/fleet/[slug] | up to 6 张 "Operated By" 卡 + FAQ 链接 | 2 列网格 + 强调色卡片 |
/airports/[slug] | "See all FAQs" 链接 | FAQ section 末尾内联 |
~2,090 条内部链接,从权威 hub 流向程序化子页。PageRank 跟着数据走。
Slug 系统的旧债
内部链接工作浮出一个旧设计问题。/insights/operators/[slug] 用从 AviGo 月度飞行报告提取的 slug(如 "netjets-aviation")。/insights/operators/[slug]/aircraft/[aircraftSlug] 配对页用 operators.ts 主表 slug(如 "netjets")。同一 URL 家族——完全不同的 slug 系统。
修复是 operator-aircraft-match.ts 里一个小桥:
export function resolveOperatorSlugFromName(operatorName: string): string | null {
const target = operatorName.toLowerCase().trim();
const operators = getAllOperators();
const exact = operators.find((o) => o.name.toLowerCase() === target);
if (exact) return exact.slug;
const partial = operators.find(
(o) => target.includes(o.name.toLowerCase()) || o.name.toLowerCase().includes(target),
);
return partial?.slug ?? null;
}
实体页把运营商名传过这个函数得到主 slug,用于出向配对页链接。两个 slug 系统都还在——但在链接边界做了桥接,而不是假装它们是同一个东西。
收尾 —— 验证时发现的两个真实 bug
- Fleet 详情页有两条渲染分支。199 架飞机里 184 是 catalog-only,提前 return 走
<CatalogDetailPage>。第一版"Operated By"section 只落在 detailed 分支——绝大多数飞机不可见。修复:在两条分支都渲染。 - IndexNow 没有
operator-entity类别。34 个/insights/operators/[slug]hub 页不在任何 IndexNow 类别里,只能通过手动urls: [...]push。现在它们有自己的 case,并且进了"all"——周一 cron 会自动覆盖。
最终数字
| 指标 | 之前 | 之后 |
|---|---|---|
| Sitemap URL(英文) | 1,750 | 4,195 |
| Hreflang 候选(× 11 语言) | ~19,250 | ~46,000 |
| 使用中的 JSON-LD 类型 | 17 | 21(+ Person、NewsArticle、SpecialOffer、IndustryInsight) |
| IndexNow 类别 | 13 | 19 |
[locale]/ 下程序化 SEO 新页面类型 | 0 | 6 |
| Hub→子页内部链接 | 0 | ~2,090 |
| 测试 | 261/261 | 261/261 |
从 8,000 到 10,000 索引页面不会一夜发生——Google 通常需要 6-8 周消化 sitemap 并爬完长尾。但我们能控制的部分都已就位:页面存在、sitemap 声明它们、IndexNow 推给 4 个引擎、hub 页向下链接、schema 发出权威信号。
下次会换种方式做的事
- 更早发现 sitemap 遗漏。Industry Insights 模块两周前发布时没带 sitemap 入口。解决方案:测试套件加一个 sitemap 覆盖断言——
app/[locale]/下每个有generateStaticParams的路由都必须出现在sitemap.ts中。这个断言会在 Industry Insights 原始 commit 时把 CI 红掉。 - 把 slug 系统类型化。同一 URL 家族两套 slug 不应该靠"字符串匹配"修——应该用
OperatorMasterSlug和OperatorEntitySlug两个 branded type,编译器拒绝混用。 - IndexNow 断言和 sitemap 入口一起加。今天有三个 commit 是"加了路由,又得想起来加 IndexNow case"。这应该是一个 TypeScript 步骤,不是三个。
第 25 天可能就是关这三个回路。今天的话:4 个 commit 进 origin/main,Vercel 部署绿,IndexNow 在推,等 Google 做它那种缓慢、深思熟虑的工作。
准备好飞行了吗?几秒钟获取个性化包机报价。
订阅资讯
空腿航班优惠、新航线与航空洞察,直达您的邮箱。