21 个页面「已抓取但未编入索引」,我是怎么一个个处理的
GSC 告诉你页面被爬了但没进索引,普遍的答案是「加内容、加内链」。我照做了,没用。真正的根因在首屏 HTML 里——46 个字符。
如果你在 Search Console 的「网页」报告里看到一栏叫 「已抓取 - 尚未编入索引」,而且数量在两位数,那你大概已经搜过一轮解决方案了。
网上的标准答案是:加内容、加内链、提高质量、等。我照做了两轮,数字没动。
后来发现问题根本不在内容质量上——在首屏 HTML 里。
先说结论
一个 126 页的内容站,接手时 21 个页面卡在「已抓取 - 尚未编入索引」。诊断出来的原因是三类:
- 3 个核心页面是纯客户端渲染,首轮 HTML 只有
Loading…,46 个字符 - 2 个页面正文只有 613 字符,薄得离谱
- 6 个页面主题重复,同一件事写了 3 遍(满月仪式 5 个 URL、月水仪式 2 个 URL)
修完之后这 21 个全部离开了那个列表。下面每一步都可以复现。
第一步:先搞清楚 Google 到底看到了什么
这是整件事最关键的一步,也是最容易被跳过的一步。
用 curl 抓页面的原始 HTML(不执行 JS),看里面有没有正文:
curl -s https://your-site.com/page \
| python3 -c "
import sys, re, html
raw = sys.stdin.read()
m = re.search(r'<main[^>]*>(.*?)</main>', raw, flags=re.S|re.I)
seg = m.group(1) if m else raw
t = re.sub(r'<(script|style)[^>]*>.*?</\1>', ' ', seg, flags=re.S|re.I)
t = re.sub(r'<[^>]+>', ' ', t)
t = re.sub(r'\s+', ' ', html.unescape(t)).strip()
print('正文长度:', len(t))
print('前 200 字:', t[:200])
"
我对自己的站跑了一遍,输出是:
正文长度: 46
前 200 字: Free Oracle Reading — Ask Anonymously Loading…
这就是答案。 Googlebot 第一次抓取时拿到的 HTML 里,除了一个 H1 和一句 Loading…,什么都没有。它能看到的"内容"是 46 个字符。
它不是不想索引,是没有东西可以索引。
为什么「等等就好」不成立
Google 确实能执行 JavaScript,但:
- 渲染是排队的,不是抓取时立刻做。一个新页面可能要等几天到几周
- 渲染有预算限制。一个站点被渲染的页面数量是有限的,尤其当你的站没什么权重
- 渲染失败的页面,Google 就当它是空页面
所以"内容全在 JS 里"这件事,代价不是"慢一点",是"可能永远不会被正确索引"。
第二步:把内容挪到服务端,但别重写整个页面
发现问题的页面是交互型页面(表单、抽牌、结果展示),业务逻辑必须留在客户端。
不需要为了 SEO 把它整个改成服务端组件。我用的办法是:在 layout 里加服务端渲染的内容区块。
// app/oracle/layout.tsx —— 服务端组件(没有 "use client")
import { SeoContentBlock } from "@/components/landing/seo-content-block";
export default function Layout({ children }: { children: React.ReactNode }) {
return (
<>
<h1>Free Oracle Reading — Ask Anonymously</h1>
{children} {/* 客户端交互部分,原样保留 */}
{/* 服务端渲染的说明内容:进入首轮 HTML */}
<SeoContentBlock
title="How an Online Oracle Reading Works"
blocks={[ /* 是什么、怎么运作、能问什么、有什么限制 */ ]}
faqs={[ /* 8 条常见问题 */ ]}
/>
</>
);
}
关键点:
layout是服务端组件,不受子页面 Suspense 边界影响,所以它的内容一定在第一版 HTML 里- 客户端页面一行没改,业务逻辑零风险
- 内容块用
<details>折叠,用户不觉得嘈杂,但搜索爬虫能读到全部文本
改完之后同一个页面:
正文长度: 3677
46 → 3677。这不是"优化",这是从"没有内容"变成"有内容"。
顺手补结构化数据
内容块里同时输出了 FAQPage 的 JSON-LD:
const jsonLd = faqs?.length ? {
"@context": "https://schema.org",
"@type": "FAQPage",
mainEntity: faqs.map(f => ({
"@type": "Question",
name: f.q,
acceptedAnswer: { "@type": "Answer", text: f.a },
})),
} : null;
注意:JSON-LD 必须和页面上真实可见的内容一致。标记了页面上没有的问答,属于结构化数据违规,会被人工处罚。
第三步:处理主题重复
这一条最容易被忽略,但对"已抓取未索引"的贡献往往最大。
我的站上有这么几组:
| 主题 | URL 数量 | 具体路径 |
|---|---|---|
| 满月仪式 | 5 | /full-moon-release-ritual、/rituals/full-moon、/blog/full-moon-ritual-guide… |
| 月水 | 2 | /blog/moon-water-ritual、/blog/moon-water-how-to-make-and-use |
| 职业解读 | 2 | /career-reading、/career-oracle-reading |
Google 的视角很简单:同一个主题你写了五遍,它只会选一个索引,剩下的留在"已抓取未索引"里。
处理方式分两种,别搞混:
A. 纯重复 → 308 永久重定向
内容基本相同、没有独立价值的,合并成一个,其余永久跳转:
// next.config.ts
async redirects() {
return [
{ source: "/blog/moon-water-ritual",
destination: "/blog/moon-water-how-to-make-and-use",
permanent: true },
{ source: "/career-reading",
destination: "/career-oracle-reading",
permanent: true },
];
}
改完记得把被跳转的页面从 sitemap 里删掉,否则你还在主动告诉 Google 去抓一堆跳转页。
B. 功能不同 → 保留,但内容必须差异化
/new-moon-ritual(介绍页)和 /rituals/new-moon(实际做仪式的工具页)不是重复,但它们当时的文案几乎一样。
这种情况不要合并,而是让两页回答不同的问题:
- 介绍页讲:这是什么、适合谁、能得到什么
- 工具页讲:今晚具体怎么做、什么时候做、需要准备什么、常见错误
我改完之后,工具页 613 字符 → 4,100+ 字符,而且和介绍页内容不重叠。
第四步:别让小问题占掉索引额度
顺手清掉的三个:
- 私人页面加 noindex。用户个人数据页(我的站是
/journal)对搜索者没有任何价值,但它会占一个索引位。加robots: { index: false, follow: true }。 - 法律页移出 sitemap。
/disclaimer、/refund-policy不需要主动请求索引。 - sitemap 瘦身。126 → 121 条,只留真正想让 Google 抓的。
结果
| 指标 | 改前 | 改后 |
|---|---|---|
| 核心页首屏正文 | 46 字符 | 3,677 字符 |
| 薄内容页 | 613 字符 | 4,100+ 字符 |
| 重复主题组 | 3 组(9 个 URL) | 合并为 3 个 URL |
| sitemap 条目 | 126 | 121 |
| 「已抓取未索引」 | 21 | 0 |
时间线:改完上线后,Google 重新抓取用了大约 2–4 周。期间我在 GSC 里手动对最重要的几个 URL 点了「请求编入索引」(每天有额度限制,约 10 个)。
你可以直接用的检查清单
□ curl 抓页面原始 HTML,统计 <main> 里的纯文本长度
→ 少于 1000 字符就是有问题
□ 检查是不是 "use client" 整页,内容是否全在 JS 里
□ GSC 里看「已抓取 - 尚未编入索引」的具体 URL 列表
□ 把这些 URL 按主题分组,找重复
□ 纯重复的 → 308 合并,并从 sitemap 删除
□ 功能不同的 → 各自补差异化内容到 2000 字以上
□ 私人页 / 法律页 → noindex 或移出 sitemap
□ 补 FAQPage 结构化数据(和可见内容一致)
一句提醒
这套办法解决的是「Google 读不懂你的页面」。它不会让你的流量翻倍——内容和需求匹不匹配,是另一个问题。
我自己的站就是例子:索引问题修完之后,那 21 个页面全部进了索引,但自然流量并没有因此暴涨。修 SEO 只是把一个"漏水的桶"补好,桶里有没有水是另一回事。
先把桶补好,再谈倒水。