做SEO的人手头都有一个关键词库,来源五花八门:5118导出来的、百度下拉框采集的、竞品网站扒的、长尾词组合工具生成的。几个来源一合并,几万条关键词里至少30%是重复或高度相似的。
大部分人处理重复关键词的方式是:扔进Excel,点"删除重复项",搞定。但Excel只能删"完全一样"的词,"深圳注册公司"和"注册公司深圳"对它来说是两条不同的数据。真正需要去重的是这些换了个顺序、改了个修饰词、本质上指向同一个搜索意图的"孪生词"。
关键词去重的三个层次
| 第一层 | 完全重复去重:两条关键词字符完全一样 → Excel删除重复项就能搞定 |
| 第二层 | 相似度去重:字符组成高度相似但顺序不同 → "深圳注册公司"和"注册公司深圳",需要编辑距离算法 |
| 第三层 | 语义去重:用词不同但搜索意图相同 → "注册公司多少钱"和"公司注册费用",需要语义模型 |
大部分在线工具只能做到第一层。第二层和第三层才是真正帮你省时间的地方。
第一层:在线工具做完全重复去重,5秒搞定
如果你的需求只是"删掉完全一样的行",下面几个在线工具都够用:
| 工具 | 单次处理量 | 去重方式 | 附加功能 |
|---|---|---|---|
| UU在线工具 uutool.cn | 10万行以内流畅 | 精确匹配 | 去空行、去首尾空格、统计去重前后数量 |
| selfboot 文本去重 | 支持大文本 | 精确匹配 | 大小写敏感选项、保留首次出现顺序、重复项统计列表 |
| ebtool 文字去重 | 100万行以内 | 精确匹配 | 区分大小写、排序输出、支持超大文件 |
这三个工具的处理逻辑一样:逐行比对,删掉内容完全相同的行。如果你的词库是5万条以内、只需要去完全重复,随便选一个就行。
Excel也能做,但有坑
Excel的"删除重复项"在处理5万行以上时可能卡死。而且Excel会把你粘贴进去的关键词自动做格式转换——比如"1-2岁"可能变成日期"1月2日"。所以超过1万行的关键词去重,优先用在线工具或Python,别用Excel硬撑。

第二层:相似度去重,这才是核心难点
在线工具搞不定的,是这类情况:
深圳注册公司代办深圳代办注册公司深圳公司注册代办代办深圳注册公司注册公司深圳代办
这5个关键词对搜索引擎来说是同一个搜索意图,但对Excel和在线去重工具来说是5条不同的数据。如果你不做相似度去重,这5个词会被当成5个不同的关键词分别建页面,导致站内关键词互相竞争。
相似度去重需要用到编辑距离算法。Python的fuzzywuzzy库是最常用的方案:
from fuzzywuzzy import fuzzimport csvdef deduplicate_keywords(keywords, threshold=90):"""基于相似度去重,保留第一个出现的词threshold: 相似度阈值,90表示90%相似就算重复"""unique = []duplicates = []for kw in keywords:is_dup = Falsefor existing in unique:# token_sort_ratio: 忽略词序,只比较词组是否相同similarity = fuzz.token_sort_ratio(kw, existing)if similarity >= threshold:is_dup = Trueduplicates.append((kw, existing, similarity))breakif not is_dup:unique.append(kw)return unique, duplicates# 读取关键词列表with open("keywords_raw.txt", "r", encoding="utf-8") as f:keywords = [line.strip() for line in f if line.strip()]print(f"原始数量: {len(keywords)}")# 第一步:精确去重keywords = list(set(keywords))print(f"精确去重后: {len(keywords)}")# 第二步:相似度去重(阈值90%)unique_kw, dup_kw = deduplicate_keywords(keywords, threshold=90)print(f"相似度去重后: {len(unique_kw)}")# 导出结果with open("keywords_deduped.txt", "w", encoding="utf-8") as f:f.write("\n".join(unique_kw))with open("duplicates_report.csv", "w", newline="", encoding="utf-8-sig") as f:writer = csv.writer(f)writer.writerow(["重复词", "保留词", "相似度"])writer.writerows(dup_kw)print(f"已导出: keywords_deduped.txt ({len(unique_kw)}条)")print(f"重复报告: duplicates_report.csv ({len(dup_kw)}组)")这里有个关键参数:相似度阈值。设多少合适?

| 阈值 | 效果 | 适用场景 |
|---|---|---|
| 95-100 | 只去重高度相似的词(词序不同但词组完全一致) | 保守策略,适合想保留最多关键词的场景 |
| 85-94 | 去掉词组相近、只差一两个字的情况 | 推荐值,兼顾去重率和保留有效词 |
| 75-84 | 可能误删搜索意图不同的词 | 激进策略,适合词库极大、需要大幅压缩的场景 |
token_sort_ratio 和 token_set_ratio 的区别
token_sort_ratio 是把两个词拆成词组后排序再比对——"深圳注册公司"和"注册公司深圳"拆词后都是{"深圳","注册","公司"},相似度100%。token_set_ratio 更宽松,只比对共有词组的比例——"深圳注册公司代办"和"深圳公司注册"共有词组比例也很高,相似度可能在85%以上。
实际使用中,先跑一遍 token_sort_ratio 去掉词序不同的重复词,再用 token_set_ratio 去掉只是增减了修饰词的近似词。
第三层:语义去重——"注册公司多少钱"和"公司注册费用"算不算重复?
从用户搜索意图来看,"注册公司多少钱"和"公司注册费用"问的是同一件事。但从字面上看,编辑距离算法会判它们相似度很低。这就是语义去重要解决的问题。
语义去重需要用到文本向量化模型,比如sentence-transformers。把每个关键词转成向量,计算向量之间的余弦相似度,高于阈值就判定为重复:

from sentence_transformers import SentenceTransformerfrom sklearn.metrics.pairwise import cosine_similarityimport numpy as np# 加载中文语义模型model = SentenceTransformer('paraphrase-multilingual-MiniLM-L12-v2')def semantic_deduplicate(keywords, threshold=0.92):"""基于语义相似度去重threshold: 余弦相似度阈值,0.92表示92%相似就算重复"""# 将所有关键词转成向量embeddings = model.encode(keywords)unique_indices = []duplicates = []for i, kw in enumerate(keywords):is_dup = Falsefor j in unique_indices:sim = cosine_similarity([embeddings[i]], [embeddings[j]])[0][0]if sim >= threshold:is_dup = Trueduplicates.append((kw, keywords[j], round(sim, 3)))breakif not is_dup:unique_indices.append(i)unique_kw = [keywords[i] for i in unique_indices]return unique_kw, duplicates# 使用示例keywords = ["注册公司多少钱","公司注册费用","注册一个公司要多少钱","公司注册流程","深圳注册公司",]unique_kw, dups = semantic_deduplicate(keywords, threshold=0.85)print("去重后保留的关键词:")for kw in unique_kw:print(f" · {kw}")print("\n被判为重复的:")for dup_kw, kept_kw, sim in dups:print(f" {dup_kw} ≈ {kept_kw} (相似度: {sim})")语义去重的优点是准——它真的能理解"多少钱"和"费用"是一个意思。缺点是慢且吃资源:1万条关键词在普通电脑上要跑几分钟,10万条可能要跑半小时以上。而且模型本身有几百MB,第一次运行要下载。
实际建议:语义去重按需使用
对于大多数SEO场景,做到第二层(相似度去重)就足够了。语义去重适合以下情况:
· 词库超过10万条,需要大幅压缩到几千条核心词
· 做的是知识型网站,同一个问题有几十种不同问法
· 准备投放SEM,预算有限需要精选高价值关键词
一套完整的关键词去重流程
把上面三层串起来,就是一套完整的关键词清洗流水线:
| 步骤 | 操作 | 工具 | 效果 |
|---|---|---|---|
| 1. 格式化清洗 | 统一全角/半角,去掉空格、标点、特殊字符 | Python / 在线文本处理工具 | 减少因格式不同导致的"假不同" |
| 2. 精确去重 | 删除字符完全相同的行 | UU在线工具 / ebtool / Excel | 去掉15%-25%的完全重复词 |
| 3. 相似度去重 | 用fuzzywuzzy删掉词序不同、高度相似的词 | Python脚本 | 再压缩10%-20% |
| 4. 语义去重(可选) | 用语义模型去重不同表达但同意图的词 | sentence-transformers | 再压缩5%-10% |
| 5. 人工抽检 | 随机抽100条检查,确认没误删有效词 | 肉眼判断 | 兜底,防止算法过度去重 |
以10万条原始关键词为例,经过这套流程后大概剩下5-6万条。被去掉的那4-5万条不是有效关键词,是干扰项。去掉它们之后,你做内容规划、内链布局、SEM选词的效率都提升一截——因为不用在重复词上反复纠结了。
不同规模下的工具选择
| 1000条以内 | Excel删除重复项 + 人工目检,不需要任何额外工具 |
| 1000-1万条 | 在线去重工具(精确去重) + fuzzywuzzy脚本(相似度去重),组合使用 |
| 1万-10万条 | Python脚本全流程自动化,fuzzywuzzy处理相似度,按需加语义去重 |
| 10万条以上 | Python + 分批处理 + 多进程加速。单进程跑10万条相似度比对可能要好几个小时,多进程可以压缩到半小时内 |
关键词去重这件事,大部分人的问题不是没有工具,而是止步于精确去重就以为做完了。几万条词库里,完全重复的词只是冰山浮在水面上的那部分,真正占大头的是水面下那些换了个顺序、改了个修饰词的相似词。花半小时跑一遍相似度去重,比你花一天时间对着Excel人工筛选的效率高得多。
