如何在chrome headless + puppeteer evaluate()中使用xpath?

时间:2018-01-25 17:19:44

标签: javascript google-chrome xpath puppeteer

如何使用$x()xpath expression内使用page.evaluate()

至于page不在同一个环境中,我直接尝试了$x()(就像我在Chrome开发工具中所做的那样),但没有雪茄。

脚本进入超时状态。

2 个答案:

答案 0 :(得分:8)

$x()不是通过XPath选择元素的标准JavaScript方法。 $x()它只是helper in chrome devtools。他们在文档中声明了这一点:

  

注意:此API仅在控制台本身内可用。您无法从页面上的脚本访问命令行API。

此处page.evaluate()被视为“页面上的脚本”。

您有两种选择:

  1. 使用document.evaluate
  2. 以下是page.evaluate()内选择元素(精选文章)的示例:

    const puppeteer = require('puppeteer');
    
    (async () => {
        const browser = await puppeteer.launch();
        const page = await browser.newPage();
        await page.goto('https://en.wikipedia.org', { waitUntil: 'networkidle2' });
    
        const text = await page.evaluate(() => {
            // $x() is not a JS standard -
            // this is only sugar syntax in chrome devtools
            // use document.evaluate()
            const featureArticle = document
                .evaluate(
                    '//*[@id="mp-tfa"]',
                    document,
                    null,
                    XPathResult.FIRST_ORDERED_NODE_TYPE,
                    null
                )
                .singleNodeValue;
    
            return featureArticle.textContent;
        });
    
        console.log(text);
        await browser.close();
    })();
    
    1. 由Puppeteer page.$x()选择元素并将其传递给page.evaluate()
    2. 此示例实现与1.示例中相同的结果:

      const puppeteer = require('puppeteer');
      
      (async () => {
          const browser = await puppeteer.launch();
          const page = await browser.newPage();
          await page.goto('https://en.wikipedia.org', { waitUntil: 'networkidle2' });
      
          // await page.$x() returns array of ElementHandle
          // we are only interested in the first element
          const featureArticle = (await page.$x('//*[@id="mp-tfa"]'))[0];
          // the same as:
          // const featureArticle = await page.$('#mp-tfa');
      
          const text = await page.evaluate(el => {
              // do what you want with featureArticle in page.evaluate
              return el.textContent;
          }, featureArticle);
      
          console.log(text);
          await browser.close();
      })();
      

      Here是一个如何向您的脚本注入$x()辅助函数的相关问题。

答案 1 :(得分:0)

如果您坚持使用page.$x(),则只需将结果传递给page.evaluate()

const example = await page.evaluate(element => {
  return element.textContent;
}, (await page.$x('//*[@id="result"]'))[0]);