如何用XPath和Puppeteer获取元素的nextSibling文本?
解决 Puppeteer 获取兄弟文本节点的问题
问题分析
- 首次尝试使用
page.evaluateHandle返回的是 JSHandle 对象而非直接文本,因此控制台输出CDPElementHandle。 - 修改后的代码错误使用
element[0],因为page.waitForXPath返回单个元素句柄而非数组,导致undefined;同时文本节点没有innerText属性,需用nodeValue获取内容。 - XPath 表达式中的
//following-sibling::text()会遍历所有后代节点的兄弟文本,应改为/following-sibling::text()[1]精准定位目标文本节点。
修正后的核心代码
在 playTest 函数中替换获取文本的逻辑:
// 定位<b>Voiced</b>的第一个兄弟文本节点 const textNodes = await page.$x("//b[contains(.,'Voiced')]/following-sibling::text()[1]"); let voicedText = null; if (textNodes.length > 0) { // 获取文本节点内容并去除多余空格 voicedText = await page.evaluate(node => node.nodeValue.trim(), textNodes[0]); } console.log(voicedText); // 存在时输出"Japanese"
关键说明
- 文本节点处理:文本节点属于 Node 类型,需通过
nodeValue获取内容,不能使用元素的innerText属性。 - XPath 优化:
/following-sibling::text()[1]直接定位目标元素的第一个兄弟文本节点,避免匹配无关内容。 - 空值处理:通过检查
textNodes.length兼容元素不存在的页面,避免报错。
完整修正后的 playTest 函数
async function playTest(url) { const { browser, page } = await startBrowser(); page.setViewport({ width: 1980, height: 1024 }); await page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'); await page.goto('https://f95zone.to/login'); await page.click(USERNAME_SELECTOR); await page.keyboard.type(C.username); await page.click(PASSWORD_SELECTOR); await page.keyboard.type(C.password); await page.click(CTA_SELECTOR); await page.waitForNavigation(); await page.goto(url); // 获取目标文本节点 const textNodes = await page.$x("//b[contains(.,'Voiced')]/following-sibling::text()[1]"); let voicedText = null; if (textNodes.length > 0) { voicedText = await page.evaluate(node => node.nodeValue.trim(), textNodes[0]); } console.log(voicedText); await closeBrowser(browser); // 新增关闭浏览器逻辑 return voicedText; }
内容的提问来源于stack exchange,提问作者Ryahn
相关产品推荐
相关产品推荐

