【问题标题】:Get href attribute in pupeteer Node.js在 puppeteer Node.js 中获取 href 属性
【发布时间】:2019-08-18 16:25:28
【问题描述】:

我知道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);
}

【问题讨论】:

    标签: node.js puppeteer


    【解决方案1】:

    我不知道为什么会这么痛苦,但是我在前一段时间遇到这个时发现了这个。

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

    【讨论】:

      【解决方案2】:

      await page.$$('a') 返回一个带有 ElementHandles 的数组——这些对象具有自己的 pupeteer-specific API,它们没有用于 HTML 元素或 DOM 节点的常用 DOM API。因此,您需要通过page.evaluate() 在浏览器上下文中检索属性/属性,或者使用相当复杂的 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);
        }
      })();
      

      【讨论】:

      • 感谢您的清晰解释。使用 page.eval() 就像一个魅力。
      • @vsemozhebuty 我们可以在 WAY 1 获取后重定向到内部 url 链接吗?
      • @Asha 抱歉,我不确定我是否理解。你能详细说明吗?或者问一个完整的问题?
      • @vsemozhebuty const hrefs1 = await page.evaluate( () => Array.from( document.querySelectorAll('a[href]'), a => a.getAttribute('href') ) );在这里,如果我想去hrefs1 url页面..如何实现?如果我写 page.goTo(hrefs1) 它的投掷页面是未定义的..
      • @Asha 不幸的是,如果没有更多的代码,就很难指出可能出了什么问题。请用一个小代码示例提出一个完整的问题。
      【解决方案3】:

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

      await page.$$eval('a', (anchors) => anchors.map((link) => (link as HTMLLinkElement).href));
      

      【讨论】:

        【解决方案4】:
        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);
        

        【讨论】:

          猜你喜欢
          • 2022-11-18
          • 2016-06-07
          • 1970-01-01
          • 1970-01-01
          • 2021-06-04
          • 1970-01-01
          • 1970-01-01
          • 2020-08-11
          • 2012-01-28
          相关资源
          最近更新 更多