如何使用Puppeteer检测指定元素(非全页面)中是否存在指定文本
问题原因
在Puppeteer的ElementHandle实例上调用$x方法时,如果XPath表达式以//开头,会默认从整个文档的根节点开始匹配元素,而非你之前选中的当前元素上下文,所以会匹配到页面其他位置的符合条件的元素。
解决方法
修改XPath表达式,以.//开头,.代表当前选中的元素节点,.//就表示只在当前元素的后代节点中匹配:
// 原错误写法 let [el] = await selector.$x(`//p[contains(text(), 'myTextString')]`); // 修正后写法 let [el] = await selector.$x(`.//p[contains(text(), 'myTextString')]`); pass = el ? true : false
可复现示例修正后代码
你提供的测试代码修改对应行后即可得到预期结果:
const puppeteer = require('puppeteer'); async function test() { const browser = await puppeteer.launch({ headless: false, defaultViewport: null, args: ['--start-maximized'] }); const page = await browser.newPage(); await page.goto('https://stackoverflow.com/'); let selector = await page.$('#notify-container'); // 新增.前缀限定在当前选中元素内匹配 let [el] = await selector.$x(`.//h2[contains(text(), 'Find the best answer to your technical question, help others answer theirs')]`); console.log(el); // 输出undefined,符合预期 pass = el ? true : false; // pass为false await browser.close(); } test();
可选替代方案
如果不想写XPath,也可以直接在evaluate方法内针对选中元素做判断:
const hasText = await selector.evaluate((el, targetText) => { return el.textContent.includes(targetText); }, 'myTextString'); pass = hasText;
内容的提问来源于stack exchange,提问作者dikuw
相关产品推荐
相关产品推荐

