Puppeteer:搜索不区分大小写的内部文本

Puppeteer: search for inner text case insensitive

我正在尝试使用 puppeteer 搜索不区分大小写的内部文本。

我读过这个:case insensitive xpath contains() possible?

例如我有这个元素:

<div>
 <span>Test One</span>
 <span>Test Two</span>
 <span>Test Three</span>
</div>

我试过失败:

const element = await page.$x("//span//text()[contains(translate(., 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), 'two')]");

不太漂亮,但您可以使用 page.evaluateHandle 和正则表达式来查找元素:

const element = await page.evaluateHandle(() =>
    Array.from(document.querySelectorAll("div > span")).find(a => /test two/i.test(a.innerText))
);

您的 XPath 表达式有效,但您 returning text() 而不是节点本身。 page.$x 期望 XPath 到 return 一个元素,因此您的代码不起作用。要 return 您需要查询 span 元素的节点。

const element = await page.$x("//span[contains(translate(text(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), 'two')]");

请注意,text() 仅适用于纯文本节点。如果您有混合内容(包含元素和文本),您应该使用字符串值(. 而不是 text()):

const element = await page.$x("//span[contains(translate(., 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), 'two')]");

为了比较我将它们放在彼此下方的表达式:

//span//text()[contains(translate(., 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), 'two')]
//span[contains(translate(text(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), 'two')
//span[contains(translate(., 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), 'two')]

第一个是span节点文本的表达式(你给的)。第二个使用 text() 查询节点本身。最后一个使用字符串值查询节点。

与 spb 类似,我会这样做:

const element = await page.evaluateHandle(() =>
 [...document.querySelectorAll('span')].find(s => s.innerText.toLowerCase().match('two'))
)