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'))
)
我正在尝试使用 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'))
)