我正在尝试使用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')]");
您的XPath表达式有效,但您将返回text()
而不是节点本身。 page.$x
期望XPath返回一个元素,因此你的代码不起作用。要返回节点,您需要查询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()
查询节点本身。最后一个使用字符串值来查询节点。
不是很漂亮,但你可以使用page.evaluateHandle
和正则表达式来找到元素:
const element = await page.evaluateHandle(() =>
Array.from(document.querySelectorAll("div > span")).find(a => /test two/i.test(a.innerText))
);
与spb类似,我会这样做:
const element = await page.evaluateHandle(() =>
[...document.querySelectorAll('span')].find(s => s.innerText.toLowerCase().match('two'))
)