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

Mev*_*pek 6 javascript xpath google-chrome puppeteer

我如何在一个内部$x()使用xpath表达式page.evaluate()

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

脚本进入超时状态.

Eve*_*tss 13

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

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

page.evaluate()在此视为"页面上的脚本".

您有两种选择:

  1. 使用 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();
})();
Run Code Online (Sandbox Code Playgroud)
  1. 选择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();
})();
Run Code Online (Sandbox Code Playgroud)

是一个如何为$x()脚本注入辅助函数的相关问题.


Gra*_*ler 6

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

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