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

时间:2019-03-28 13:01:52

标签: javascript node.js xpath web-scraping puppeteer

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

我已阅读:case insensitive xpath contains() possible?

例如,我有以下元素:

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

我尝试失败了:

$("body, html").animate({
    scrollTop: $("#accordian-block-1").position().top
});

3 个答案:

答案 0 :(得分:3)

您的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()查询节点本身。最后一个使用字符串值查询节点。

答案 1 :(得分:2)

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

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

答案 2 :(得分:0)

类似于spb,我会这样做:

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