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

Posted

技术标签:

【中文标题】如何在chrome headless + puppeteer评估()中使用xpath?【英文标题】:How to use xpath in chrome headless+puppeteer evaluate()? 【发布时间】:2018-07-05 00:56:36 【问题描述】:

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

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

脚本超时。

【问题讨论】:

【参考方案1】:

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

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

page.evaluate() 在这里被视为“页面上的脚本”。

你有两个选择:

    使用document.evaluate

这是在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();
)();
    通过 Puppeteer page.$x() 选择元素并将其传递给 page.evaluate()

这个例子实现了和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() 辅助函数注入到您的脚本中。

【讨论】:

你知道在evaluate() 中添加脚本来加载一些自定义函数的方法吗?在github.com/GoogleChrome/puppeteer/blob/master/docs/api.md 上找不到include 或类似内容 @wam 写一个新问题,更清楚地说明您的问题,我们会尽力帮助您。【参考方案2】:

如果你坚持使用page.$x(),你可以简单地将结果传递给page.evaluate()

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

【讨论】:

以上是关于如何在chrome headless + puppeteer评估()中使用xpath?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Jenkins env 变量中为 Headless Chrome 配置 CHROME_BIN 路径

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

如何模仿或设置 Chrome Headless 插件

Chrome Headless puppeteer CPU 过多

如何避免在 Angular 测试阶段出现以下问题:Chrome Headless has not capture in 60000 ms, kill

GitLab 是如何用 Headless Chrome 测试的