【问题标题】:Puppeteer and JSHandle@node aria-label howTo?Puppeteer 和 JSHandle@node aria-label 如何?
【发布时间】:2021-09-25 08:40:28
【问题描述】:

我正在使用 puppeteer 尝试从下面的查询中访问“aria-label”属性,但它返回的结果类型为:

    JSHandle@node

这意味着当我尝试 .getAttribute('aria-label') 时,它是 undefined

我正在尝试从 flatpickr 日历中获取可用日期列表。

谁能告诉我如何正确地做到这一点?

谢谢。

(async () => {

    const arias = await page.evaluate(() => {
        const results = document.querySelectorAll('span.flatpickr-day:not(.prevMonthDay):not(.nextMonthDay):is(.flatpickr-disabled)');
        dates = {};
        if (results.length) {
            for ( var i = 0; i < results.length; i++ ) {
                dates.push(results[i].getAttribute('aria-label'));
            }
        }
        return dates;
    });

})

【问题讨论】:

  • 您能确认您的dates 是您原始代码中的一个数组吗?像这样(作为一个空对象,{})它会抛出一个 TypeError。除此之外,您能否与 flatpickr 日历共享页面的 URL?对我来说,如果我修复脚本上方的 dates 类型就可以了。
  • 请分享您正在抓取的页面的 URL 或示例代表性标记。 dates 应该是一个数组,而不是一个对象。对象没有属性push,如果您将侦听器附加到浏览器控制台以检查错误,您会看到它。

标签: javascript node.js puppeteer javascript-objects flatpickr


【解决方案1】:

当您遇到evaluate 的问题时,第一步是到add a listener to browser console.logs 并自己在浏览器中尝试代码。

让我们尝试在浏览器本身中运行代码,不使用 Puppeteer,这样我们可以看看是否有任何错误:

const results = document.querySelectorAll("div");
dates = {};

if (results.length) { // unnecessary; if results.length is 0, the loop won't run
  for (var i = 0; i < results.length; i++) {
    dates.push(results[i].getAttribute('aria-label'));
  }
}

console.log(dates);
&lt;div aria-label="foobar"&gt;baz&lt;/div&gt;

这给出了Uncaught TypeError: dates.push is not a function。您可能的意思是 dates 是一个数组,而不是一个对象:

const results = document.querySelectorAll("div");
dates = [];

for (var i = 0; i < results.length; i++) {
  dates.push(results[i].getAttribute('aria-label'));
}

console.log(dates);
&lt;div aria-label="foobar"&gt;baz&lt;/div&gt;

将其放入 Puppeteer 中,我们可以将其缩短为:

const puppeteer = require("puppeteer");

let browser;
(async () => {
  browser = await puppeteer.launch();
  const [page] = await browser.pages();
  await page.setContent('<div aria-label="foobar">baz</div>');

  const arias = await page.evaluate(() => Array.from(
    document.querySelectorAll("div"), 
    e => e.getAttribute("aria-label")
  ));
  
  // or:
  //const arias = await page.$$eval("div", els => 
  //  els.map(e => e.getAttribute("aria-label"))
  //);

  console.log(arias); // => [ 'foobar' ]
})()
  .catch(err => console.error(err))
  .finally(async () => await browser.close())
;

我没有方便的 flatpickr,所以我假设您的选择器在上面的代码中替换 "div" 以及您正在抓取的实际站点是有效的。

【讨论】:

    猜你喜欢
    • 2014-05-13
    • 2019-01-11
    • 2013-11-06
    • 1970-01-01
    • 2019-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-07
    相关资源
    最近更新 更多