标签页太多拖累 SEO?别急着用 robots.txt 屏蔽
前阵子折腾完 llms.txt,又顺手盯上了博客的 SEO。起因是我数了一下标签:35 篇文章,居然攒出了 69 个标签,其中将近一半(49 个)只挂着孤零零一篇文章——JWT、Monaco、Next.js、manim……这些 /tags/xxx 页面,内容基本就是把那一篇文章又列了一遍,是典型的「薄内容」(thin content)。
我的第一反应跟很多人一样:在 robots.txt 里 Disallow: /tags/,让搜索引擎别去爬这些垃圾 URL,省得它们污染索引。动手之前查了一圈,发现这个直觉是错的——准确说,是「用错了工具」。记一下这个坑,以及最后实际怎么改的。
robots.txt 到底管什么
这是最容易搞混的一点:robots.txt 的 Disallow 管的是「爬不爬」,不是「收不收录」。
这两件事是分开的。Disallow 只是告诉爬虫「这个路径你别进去抓」,但它管不住「收录」。只要别的地方有链接指向 /tags/JWT/,Google 照样可以把这个 URL 收进索引——只不过因为它被禁止抓取,没法读到页面内容,于是就在搜索结果里显示成一条没有标题、没有摘要的「裸 URL」。这种条目比薄内容还难看。
更要命的是第二层:一旦 Disallow,你就把自己的后路也堵死了。 假设你后来想把这些页面彻底从索引里删掉,正规做法是给页面加 noindex 标记(下面会讲)。但 noindex 写在页面的 HTML 里,爬虫得先「爬进去」才能看到它。你都 Disallow 了,爬虫进不来,自然读不到 noindex,于是这些页面就卡在一个「想删却删不掉」的尴尬状态里。
官方文档其实把这话说得很直白。Google 的 robots.txt 说明里明确写着:robots.txt 不是用来阻止网页被收录的机制,想让网页不出现在搜索结果里,应该用 noindex 或者加密码保护。
至于「省爬取预算(crawl budget)」这个最常被搬出来的理由——对一个 35 篇文章的小站来说根本不成立。Google 爬几百个 URL 毫无压力,crawl budget 是那种几十万页的大站才需要操心的事。所以用 Disallow 来解决我这个问题,是个三输的选择:删不干净、留裸 URL、还顺便切断了标签页向正文传递的内链权重。
正确的工具:noindex, follow
真正该用的,是写在页面 <head> 里的这一行:
<meta name="robots" content="noindex, follow">
拆开看这两个词:
noindex——告诉搜索引擎「这个页面别收录」。这才是直接、明确地把薄页面踢出索引的开关。follow——「但页面里的链接你还是要顺着爬」。标签页本身不值得收录,可它列着一堆通往正文文章的链接,这些链接得留着,让爬虫顺藤摸瓜爬到真正有价值的文章,内链权重也能正常传递。
注意这里有个关键前提,跟上一节正好呼应:robots.txt 必须保持全开,Google 才爬得进来、读得到这条 noindex。 所以「Disallow + noindex」是自相矛盾的组合,千万别同时上。两条路的区别我画了张图:
在 Astro 里怎么改
这个博客所有页面的 <head> 都走同一个 BaseHead.astro 组件,所以加个开关很简单。先给它一个 noindex 属性:
interface Props {
// ...原有字段
/** 给标签、分类这类薄页面用:不进索引,但仍让爬虫顺着链接爬到正文 */
noindex?: boolean;
}
const { /* ...其他 */ noindex } = Astro.props;
然后在合适的位置条件渲染那行 meta:
<link rel="canonical" href={canonicalURL} />
{noindex && <meta name="robots" content="noindex, follow" />}
剩下就是在四个 taxonomy 页面上把这个开关打开——标签列表页、单个标签页、分类列表页、单个分类页:
<!-- src/pages/tags/[tag].astro 等四个文件 -->
<BaseHead title={`Tag: ${tag} · ${SITE_TITLE}`} description={SITE_DESCRIPTION} noindex />
正文文章页和首页完全不动,照常被收录。改完 pnpm build,去 dist/ 里抓一下生成的 HTML 验证:标签页、分类页都带上了 noindex, follow,而博客正文页里搜不到 robots 这个 meta——符合预期。
别忘了 sitemap 这条腿
noindex 只是三件套里的一件。我之前其实已经在 astro.config.mjs 的 sitemap 配置里,把 /tags 和 /categories 过滤掉了:
sitemap({
filter: (page) =>
!/\/(tags|categories)(\/|$)/.test(new URL(page).pathname),
}),
把这几样配合起来看,逻辑才完整:
- 不主动提交——sitemap 里不放它们,等于不向 Google 推荐;
- 不收录——页面上的
noindex把它们挡在索引外; - 但允许爬——
robots.txt全开 +follow,保证爬虫能进来读到noindex,也能顺着链接爬到正文。
三条缺一不可。尤其别犯那个最经典的错:既在 sitemap 排除、又在 robots.txt 里 Disallow、还指望 noindex 生效——后两个是打架的。
几点保留判断
- 生效要等重爬。 加了
noindex不是立刻见效。如果这些标签页之前已经被收录过,得等 Google 下次重新爬到它、读到这行标记,才会把它从索引里拿掉,这个过程通常要几天到几周。想催一下,可以去 Search Console 用「网址检查 → 请求编入索引」手动点几个。 - 要不要全
noindex,是个取舍。 我这次是把所有标签页一刀切全noindex了,图省心。更精细的做法是只noindex那些「单篇标签」,给文章数多的标签(我这是AI、Claude Code、Linux这几个)留着可索引——它们算是有聚合价值的主题入口,偶尔能吃到点「主题词」的流量。但那要写判断逻辑,对我这种规模收益不大,所以我选了简单的那条。你的站如果标签普遍都挂着不少文章,可能就不该全关。 - 这事有多大用,我也不敢吹。 薄内容会不会真的拖累 SEO、
noindex之后排名会不会变好,这些我没有可量化的对照数据,纯粹是按「让索引保持干净」这个通行的最佳实践在做。官方怎么说是一回事,具体落到我这个小站有多少实际影响,自己打个折扣。我能确定的只有一点:至少别用robots.txt去Disallow,那个是实打实的反效果。
小结
- 标签页、分类页这类「一篇文章撑一页」的薄内容,确实是索引里的噪音,值得收拾;
- 但别用
robots.txt的Disallow——它只挡爬取不挡收录,会留下删不掉的裸 URL,还切断内链权重; - 正确工具是页面里的
<meta name="robots" content="noindex, follow">:不收录该页,但仍顺着链接爬到正文; - 前提是
robots.txt保持全开,Google 才读得到这条noindex,所以两者不能同时上; - 配合 sitemap 排除,凑成「不提交 + 不收录 + 但可爬」三件套,逻辑才自洽。