内容站怎么避免内容重复:在 Google 之前先发现自己的重复页

站点过几百篇之后,内容重复会直接把收录拖死。用脚本化流程在 Google 发现之前先把重复页揪出来。

内容站的”重复”很少是两篇一模一样的文章。几乎都是两篇文章在打同一个意图——标题不同、措辞不同、但底层 query 一样。Google 挑一个,把另一个降权。快速扩内容时,没有脚本化流程几乎肯定会出这个问题。

问题背景

重复分三种:(1) 完全相同(同一篇发了两次,少见),(2) 近重复(同一篇被改写过——AI 辅助下常见),(3) 重复意图(不同文章打同一个 query——最坏的一种,因为人眼看不出)。三种问题各有各的修法,过了 200 篇之后没法手工做。

判断标准

  • 两篇文章在 Search Console 上对同一 query 反复抢位置。
  • Search Console 报告的 indexed 数远低于 submitted 数——差距超过 5% 就要注意。
  • Pages 报告里出现 “Duplicate without user-selected canonical” 或 “Duplicate, Google chose different canonical”。
  • 两篇文章的 H1 去掉修饰语后讲的是同一件事。
  • sitemap 里的条数超过你独立主关键词的数量。

开始前准备

  • 这是一次 content-ops 清理,不是上线。预留 1-2 小时专注时间。
  • 内容库要有备份——跑合并脚本之前 git status 必须干净。
  • 确认托管层支持 301——Astro + _redirects、Firebase redirects、Vercel vercel.json 都行。

实操步骤

  1. 给每篇 frontmatter 加 primaryKeyword 字段。 一个字符串告诉你这篇文章服务什么。已有形态参考:
---
title: "How to Submit a Sitemap to Search Console"
urlSlug: "submit-sitemap-search-console"
primaryKeyword: "submit sitemap search console"
category: "indie-dev"
---
  1. 跑一份”重复关键词报告”。 30 行的 Node 脚本扫一遍内容库,打出任何被两篇文章共享的 keyword:
// scripts/find-duplicate-keywords.mjs
import { readdirSync, readFileSync } from 'node:fs';
import { join } from 'node:path';
import matter from 'gray-matter';

const ROOT = 'src/content/articles/zh';
const byKw = new Map();

for (const cat of readdirSync(ROOT)) {
  for (const file of readdirSync(join(ROOT, cat))) {
    if (!file.endsWith('.mdx')) continue;
    const { data } = matter(readFileSync(join(ROOT, cat, file), 'utf8'));
    const kw = (data.primaryKeyword || '').toLowerCase().trim();
    if (!kw) continue;
    if (!byKw.has(kw)) byKw.set(kw, []);
    byKw.get(kw).push(`${cat}/${file}`);
  }
}

for (const [kw, files] of byKw) {
  if (files.length > 1) console.log(`DUP "${kw}":\n  ${files.join('\n  ')}`);
}

挂到 npm run audit:content 里,重复直接让 prebuild 失败。

  1. 近重复用 301 合并。 选权重高的那篇(Search Console 看 impressions),把另一篇的独特段落搬过去,然后加 redirect。Firebase 写法:
{
  "hosting": {
    "redirects": [
      { "source": "/articles/scale-ai-content-safely",
        "destination": "/articles/scale-content-with-ai-safely",
        "type": 301 }
    ]
  }
}

Astro 静态 + Netlify 风格 _redirects

/articles/scale-ai-content-safely  /articles/scale-content-with-ai-safely  301
  1. 重复意图:缩范围或 noindex。 要么拆角度(一篇新手、一篇进阶),改 H1 和 primaryKeyword;要么把弱的那篇标 draft: true,meta 加 noindex。文章布局里写:
{frontmatter.noindex && <meta name="robots" content="noindex,follow" />}
  1. 全站默认 self-canonical,只在确认目标更强时跨页指向。Astro 布局里:
<link rel="canonical" href={`${Astro.site}${Astro.url.pathname}`} />
  1. AI 批量出稿前过一遍相似度检查。 OpenAI embedding 跑 title + 首段 cosine 就能抓出大部分:
// scripts/similarity-check.mjs(节选)
import OpenAI from 'openai';
const client = new OpenAI();

async function embed(text) {
  const r = await client.embeddings.create({
    model: 'text-embedding-3-small',
    input: text,
  });
  return r.data[0].embedding;
}

function cosine(a, b) {
  let dot = 0, na = 0, nb = 0;
  for (let i = 0; i < a.length; i++) {
    dot += a[i] * b[i];
    na += a[i] * a[i];
    nb += b[i] * b[i];
  }
  return dot / (Math.sqrt(na) * Math.sqrt(nb));
}

// cosine > 0.85 的对人工复核。
  1. 清理上线后,让 Google 重新抓。 用 URL Inspection 检查被合并的那个 URL,再对存活的那个 “Request indexing”。批量重定向后重新提交 sitemap。

执行检查清单

  • 每篇文章都有 primaryKeyword;audit 脚本在 prebuild 标记重复。
  • 301 写在 firebase.json / vercel.json / _redirects,不是只在文章正文里说。
  • 默认全站 self-canonical;跨页 canonical 是 per-article 显式开启。
  • 相似度检查接到 AI 内容流水线里,不是手动跑。

上线后验证

  • 用 Search Console URL Inspection 重抓被合并的 URL,确认返回 301 + 目标是主 URL。
  • 1-2 周后再看 Pages 报告:“Duplicate” 类原因数应下降。
  • 确认 sitemap 里不再列被合并的 URL(grep build 输出)。

容易踩的坑

  • 相信”标题不同 = 文章不同”。意图比措辞重要得多——表现是两篇在 Search Console 里互抢曝光。
  • 用 canonical “掩盖”重复但不解决问题。Google 不认同你的 canonical 时会忽略——Pages 报告会显示 “Google chose different canonical”。
  • 生成”10 best X for [职业]“这种 90% 相似的页面。这种模式会触发 helpful content 处理,整个 cluster 一起掉。
  • 把去重当一次性清理。它是持续的,每月都会新长出来——把检查接进 prebuild。
  • 301 到一个本身也 301 的 URL。链式 redirect 会损耗信号;永远只跳一次。
  • 合并后忘了从 sitemap 移除老 URL——Google 会一直抓一直再次标记。

FAQ

  • 同文的中英文版本算重复吗?: 不算,前提是 hreflang 配对。EN 和 ZH 是两个 URL 服务两类受众。两边都要 <link rel="alternate" hreflang="..."> 互指。
  • Google 会因重复扣分吗?: 大多数情况下不会有 manual penalty,但弱的那篇会被压制,比例一高,站级质量信号也会受影响。
  • 直接 noindex 不行吗?: 可以,但浪费了写作精力。301 合并保留链接权重,noindex 适合没东西可合时。
  • 怎么大规模检测近重复?: embedding + title + 首段 cosine 效果不错,超过 0.85 的应该人工复核。
  • 相似度脚本阈值设多少?: 复核线 0.85、CI 阻断线 0.92。如果总在近邻题上误报,再往下调。

相关阅读

标签: #独立开发 #内容运营 #SEO #建站策划 #Canonical #Technical SEO