在 puppeteer 中获取 href 属性 Node.js

Get href attribute in pupeteer Node.js

我知道evaluate等常用方法获取puppeteer中的元素,但我很好奇为什么我无法获取JavaScript中的href属性- 像

这样的方法
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);
}

不知道为什么这么痛,前段时间遇到这个的时候发现了。

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

await page.$$('a') returns 一个带有 ElementHandles 的数组——这些对象有自己的 pupeteer-specific API,他们没有通常的 DOM API HTML 个元素或 DOM 个节点。因此,您需要通过 page.evaluate() 在浏览器上下文中检索 attributes/properties 或使用相当复杂的 ElementHandles API。这是两种方式的示例:

'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);
  }
})();

通过使用 TypeScript 用户的 HTMLLinkElement 泛型进行转换,返回字符串数组作为链接的 href 的类型安全方式:

await page.$$eval('a', (anchors) => anchors.map((link) => (link as HTMLLinkElement).href));
const yourHref = await page.$eval('selector', anchor => anchor.getAttribute('href'));

但如果使用手柄,您可以

const handle = await page.$('selector');
const yourHref = await page.evaluate(anchor => anchor.getAttribute('href'), handle);