【问题标题】:Puppeteer: search for inner text case insensitivePuppeteer:搜索内部文本不区分大小写
【发布时间】:2019-08-19 06:26:07
【问题描述】:

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

【问题讨论】:

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


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 请注意,当您有混合内容(文本和标记)时,最好不要使用文本节点而是使用字符串值:此表达式//span[contains(translate(.,'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'),'two')] 将选择此&lt;span&gt; this &lt;em&gt;IS&lt;/em&gt; two.&lt;/span&gt;
      • @Alejandro 感谢您的评论。我在答案中添加了表达式。
      【解决方案3】:

      类似于 spb,我会这样做:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-15
        • 2013-09-26
        • 2023-03-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多