web-dev-qa-db-fra.com

Comment utiliser xpath dans chrome headless + puppeteer assess ()?

Comment puis-je utiliser $x() pour utiliser expression xpath à l'intérieur d'un page.evaluate() ?

Dans la mesure où page n'est pas dans le même contexte, j'ai essayé $x() directement (comme je le ferais dans chrome dev tools), mais pas de cigare.

Le script passe en timeout.

6
MevatlaveKraspek

$x() n'est pas une méthode JavaScript standard pour sélectionner un élément par XPath. $x() ce n'est qu'un helper in chrome devtools . Ils le prétendent dans la documentation:

Remarque: Cette API est uniquement disponible à partir de la console elle-même. Vous ne pouvez pas accéder à l'API de ligne de commande à partir de scripts sur la page.

Et page.evaluate() est traité ici comme un "script sur la page".

Vous avez deux options:

  1. Utilisez document.evaluate

Voici un exemple de sélection d'élément ( article vedette) à l'intérieur de 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. Sélectionnez l'élément par Puppeteer page.$x() et passez-le à page.evaluate()

Cet exemple obtient les mêmes résultats que dans l'exemple 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();
})();

Ici est une question connexe sur la façon d'injecter la fonction d'assistance $x() à vos scripts.

13
Everettss

Si vous insistez pour utiliser page.$x() , vous pouvez simplement passer le résultat à page.evaluate() :

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