【问题标题】:Grab all hrefs with Puppeteer使用 Puppeteer 获取所有 href
【发布时间】:2021-06-04 08:23:17
【问题描述】:
const href = await page.evaluate(() => {
  let array = Array.from(document.querySelectorAll("table tr td a").href);
  return array.map((array) => array.innerText);
});

我一直在尝试使用这个 JS 块来执行此操作,但它不起作用,它只是不断返回 undefined。

但是当我做document.querySelector("table tr td a").href; 时它可以工作,但它只给出第一个(有多个)!

我该如何正确操作?

【问题讨论】:

    标签: javascript html node.js web-scraping puppeteer


    【解决方案1】:

    在调试注入驱动浏览器的 Puppeteer 序列化代码时,请记住:

    • 代码在浏览器上下文中运行
    • 状态不与 Node 环境共享,除非通过序列化参数和返回值(您无法在浏览器中访问 Node 函数或 ElementHandles)
    • 默认情况下,页面console.logs 在 Node 环境中不可见

    考虑到这些,您可以attach console.log handlers 帮助您在 Node.js 中调试浏览器代码。在许多情况下,您可以简单地在 Puppeteer 之外在抓取页面上的控制台中手动执行它,以验证它是否有效,如下所示。

    这里的问题是querySelector(返回匹配 CSS 选择器的第一个元素)和 querySelectorAll(返回匹配选择器的所有元素的 NodeList)之间存在差异。 .href 不是 NodeList 对象的属性;此属性访问需要使用map 应用于NodeList 中的每个元素,将NodeList 转换为数组后可用。

    一旦您赋予自己console.log 的能力,就可以轻松地进行调试,只需打印每个函数调用的返回值以查看存在哪些属性。

    下面的代码说明了这两个函数之间的区别,并且在 Puppeteer 中就像在堆栈 sn-p 中一样工作得很好:

    // print first element's href
    console.log(document.querySelector("table tr td a").href);
    
    // print all elements' hrefs
    console.log([...document.querySelectorAll("table tr td a")].map(e => e.href));
    <table>
      <tr>
        <td>
          <a href="foo.html">foo</a>
          <a href="bar.html">bar</a>
          <a href="baz.html">baz</a>
        </td>
      </tr>
    </table>

    【讨论】:

      猜你喜欢
      • 2020-05-29
      • 2019-06-18
      • 2019-08-18
      • 2019-10-27
      • 2021-08-19
      • 1970-01-01
      • 2019-05-13
      • 2022-11-18
      • 2019-09-11
      相关资源
      最近更新 更多