如何使用Puppeteer统计网页中特定文本的出现次数?
使用Puppeteer实现类似Ctrl+F的文本搜索与计数
要实现和Chrome/Firefox原生Ctrl+F完全一致的文本搜索及计数功能,核心是模拟浏览器对可见文本的遍历与匹配逻辑,以下是完整实现方案:
完整代码
const puppeteer = require('puppeteer'); (async () => { const browser = await puppeteer.launch(); const page = await browser.newPage(); await page.goto('https://example.com', { waitUntil: 'networkidle2' }); // 配置搜索参数,对应Ctrl+F的可选功能 const searchText = 'example'; const caseSensitive = false; // 是否区分大小写 const wholeWord = false; // 是否全字匹配 // 在浏览器环境内执行原生搜索逻辑 const matchCount = await page.evaluate(({ searchText, caseSensitive, wholeWord }) => { let count = 0; // 创建TreeWalker遍历所有可见文本节点 const treeWalker = document.createTreeWalker( document.body, NodeFilter.SHOW_TEXT, { acceptNode: node => { const parent = node.parentElement; if (!parent) return NodeFilter.FILTER_REJECT; const style = getComputedStyle(parent); // 过滤隐藏元素和非显示标签内的文本 if (style.display === 'none' || style.visibility === 'hidden' || ['SCRIPT', 'STYLE', 'NOSCRIPT', 'IFRAME'].includes(parent.tagName)) { return NodeFilter.FILTER_REJECT; } return NodeFilter.FILTER_ACCEPT; } } ); // 生成符合Ctrl+F规则的正则表达式 let regexPattern = searchText.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // 转义正则特殊字符 if (wholeWord) regexPattern = `\\b${regexPattern}\\b`; const regex = new RegExp(regexPattern, caseSensitive ? 'g' : 'gi'); // 遍历文本节点并统计匹配次数 let currentNode; while ((currentNode = treeWalker.nextNode())) { const matches = currentNode.textContent.match(regex); if (matches) count += matches.length; } return count; }, { searchText, caseSensitive, wholeWord }); console.log(`文本"${searchText}"的出现次数:${matchCount}`); await browser.close(); })();
关键逻辑说明
- 可见文本过滤:通过
TreeWalker遍历文本节点,排除script、style等非显示元素,以及display:none、visibility:hidden的隐藏文本,和Ctrl+F只搜索可见内容的逻辑完全一致。 - 匹配规则对齐:转义搜索文本中的正则特殊字符,根据配置生成对应正则,完美对应Ctrl+F的"区分大小写"和"全字匹配"选项。
- 准确计数:遍历每个合格的文本节点,统计节点内的匹配次数并累加,得到全局总次数。
内容的提问来源于stack exchange,提问作者Caesar
相关产品推荐
相关产品推荐

