web-dev-qa-db-fra.com

Obtenir l'attribut href dans pupeteer Node.js

Je connais les méthodes courantes telles que evaluate pour capturer les éléments dans puppeteer, mais je suis curieux de savoir pourquoi je ne peux pas obtenir l'attribut href dans une approche de type JavaScript comme

const page = await browser.newPage();

await page.goto('https://www.example.com');

let links = await page.$$('a');
for (let i = 0; i < links.length; i++) {
  console.log(links[i].getAttribute('href'));
  console.log(links[i].href);
}
11
Googlebot

await page.$$('a') renvoie un tableau avec ElementHandles - ce sont des objets avec leur propre API spécifique à l'élève, ils n'ont pas d'API DOM habituelle pour les éléments HTML ou les nœuds DOM. Vous devez donc soit récupérer les attributs/propriétés dans le contexte du navigateur via page.evaluate(), soit utiliser l'API ElementHandles plutôt compliquée. Voici un exemple dans les deux sens:

'use strict';

const puppeteer = require('puppeteer');

(async function main() {
  try {
    const browser = await puppeteer.launch();
    const [page] = await browser.pages();

    await page.goto('https://example.org/');

    // way 1
    const hrefs1 = await page.evaluate(
      () => Array.from(
        document.querySelectorAll('a[href]'),
        a => a.getAttribute('href')
      )
    );

    // way 2
    const elementHandles = await page.$$('a');
    const propertyJsHandles = await Promise.all(
      elementHandles.map(handle => handle.getProperty('href'))
    );
    const hrefs2 = await Promise.all(
      propertyJsHandles.map(handle => handle.jsonValue())
    );

    console.log(hrefs1, hrefs2);

    await browser.close();
  } catch (err) {
    console.error(err);
  }
})();
18
vsemozhetbyt

Je ne sais pas pourquoi c'est une telle douleur, mais cela a été trouvé lorsque je l'ai rencontré il y a quelque temps.

async function getHrefs(page, selector) {
  return await page.$$eval(selector, anchors => [].map.call(anchors, a => a.href));
}
5
Phix