直接用 document.body.innertext + set 去重会漏掉隐藏元素内容、破坏段落结构、丢失标签语义、忽略 script/style 文本,且无法处理语义重复问题。

直接提取 HTML 内文本再用 Set 去重,大概率得到一堆空格、换行、重复标签名或语义混乱的“假唯一项”——这不是去重,是扔掉结构后胡乱拼凑。
document.body.innerText + Set 会漏掉什么
很多人第一反应是:new Set(document.body.innerText.split(/\s+/))。这看似简单,实际问题密集:
- 所有嵌套标签的文本被扁平合并,
<p>Hello<strong>world</strong></p>变成"Hello world",但你可能只想取<strong></strong>里的关键词 -
innerText会跳过display: none、visibility: hidden元素,也会受 CSS 字体渲染影响(如某些字体下空格宽度归零导致连词) - 换行符、制表符、连续空格全被压缩成单空格,
"a\n\nb"→"a b",但你可能需要保留段落边界做分句 - 脚本、注释、
<style></style>、<script></script>内容虽不显示,却仍可能被innerText忽略——你以为去重的是“可见文本”,其实连可见性都没真正校验
querySelectorAll + textContent 是更可控的起点
若目标明确(比如只取所有 <h2></h2> 标题、或所有 <li> 列表项),应绕过 innerText,改用 textContent 配合选择器:
它不触发渲染、不读样式、不跳过隐藏元素,且返回原始 DOM 树中的纯文本节点内容(含空格与换行,但不含标签)。
- 用
document.querySelectorAll('h2, h3')比document.body.innerText更精准锁定语义区块 - 对每个元素调用
.textContent.trim(),而非全局切分,避免把“标题1副标题”错拆成两个词 - 若需忽略空白行,加判断:
if (el.textContent.trim()) { ... } - 大小写敏感?统一转小写:
el.textContent.trim().toLowerCase();但注意:中文、数字、符号不受影响,无需额外处理
去重前必须做语义归一化,否则 Set 白忙
Set 只比内存地址或字符串字面量,它不理解“北京”和“北京市”是同一实体,“user_id”和“userId”是同一字段。常见归一化操作:
- 去除首尾不可见字符:
.trim()后再加.replace(/^[\u200B-\u200D\uFEFF]+|[\u200B-\u200D\uFEFF]+$/g, '')(清理零宽空格等) - 折叠内部多余空白:
.replace(/\s+/g, ' '),防止 “hello world” 和 “hello world” 被视为不同 - 忽略标点差异(如中英文逗号、括号):
.replace(/[,,。!?;:""''()\[\]]/g, ''),按需启用 - 若处理多语言,慎用
.toLowerCase()—— 土耳其语中I的小写是ı,不是i;建议用.toLocaleLowerCase('en-US')显式指定区域
超大 HTML 字符串在主线程里别用 DOMParser 全量解析
如果你手头是几 MB 的本地 HTML 字符串(比如爬虫导出文件),用 DOMParser().parseFromString(htmlStr, 'text/html') 极易卡死或 OOM。此时应切换策略:
- 用正则粗筛关键标签块(如
/<h>([^/gi</h>),再对匹配结果做textContent提取 —— 快、轻、可控,适合非嵌套结构 - 真要保 DOM 安全性?分片处理:把 HTML 按
<section></section>或<article></article>拆成数组,每批 ≤200 行,用 Web Worker 分批解析并归一化,主线程只聚合指纹 - 避免
innerHTML = htmlStr再查 —— 这会执行所有内联脚本、加载图片、触发重排,纯属自找麻烦 - 若只是去重链接或邮箱,直接上
re.findall(r'href=["\'](.*?)["\']', htmlStr)(Python)或htmlStr.match(/href=["\'](.*?)["\']/g)(JS),别碰 DOM
最常被忽略的一点:去重目标不是“字符串不重复”,而是“语义不重复”。一个 <strong>API</strong> 和一个 <code>API 在文本层面相同,但语义角色完全不同——该不该合并,得看你的下游用途,而不是交给 Set 一判了之。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











