如何读取CDPJSHandle {}的值?

问题描述 投票:0回答:1

我只是想从网站上删除一些东西。

在尝试访问元素上的属性值时遇到问题。该值返回

CDPJSHandle {}
而不是我期望的对象。

import * as puppeteer from "puppeteer";

const main = async () => {
  const browser = await puppeteer.launch({
    headless: false,
  });
  const page = await browser.newPage();

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

  const element = await page.$('canvas');
  const properties = await element.getProperties();
  const [firstKey]  = await properties.keys();
  const propertyValue = await element.getProperty(firstKey);

  console.log({
    element,        // CDPElementHandle { handle: CDPJSHandle {} },
    properties,     // Map(1) { 'jQuery3700346878389459100542' => CDPJSHandle {} },
    firstKey,       // 'jQuery3700346878389459100542',
    propertyValue,  // CDPJSHandle {}
  });

  await browser.close();
}

main();

这个

jQuery3700346878389459100542
是附加到此 html 元素的自定义属性。我可以通过浏览器使用
document.querySelector('canvas').jQuery370058052487285485872;
访问该属性,它会返回我期望的对象。

我知道类似的问题已经被问到这里,如果我引用原生 HTML 元素属性,这个问题将会起作用。然而,我的情况有所不同,因为我正在寻找自定义属性。

const evaluatedValue = await element?.evaluate((el, firstKey) => el[firstKey], firstKey);
const evaluatedTextValue = await element.evaluate(el => el.id);

console.log({
  evaluatedValue, // undefined
  evaluatedTextValue, // '\n                        '
});

如何正确访问该属性?

javascript web-scraping puppeteer
1个回答
0
投票

我不确定您最终想要获取什么数据,所以这可能是一个 XY 问题,因为可能有一种更直接的方法来解决您的实际问题,但以下是您如何从中提取一些数据动态圆形物体:

import puppeteer from "puppeteer"; // ^22.7.1

const url = "<Your URL>";

let browser;
(async () => {
  browser = await puppeteer.launch();
  const [page] = await browser.pages();
  await page.goto(url, {waitUntil: "domcontentloaded"});
  await page.waitForFunction(`
    Object.keys(
      document.querySelector("canvas")
    ).some(k => k.startsWith("jQuery"))
  `);
  const data = await page.$eval("canvas", el => {
    const {isEventSeries, needsDateAndTime, src} =
      Object.entries(el).find(([k, v]) =>
        k.startsWith("jQuery")
      )[1];
    return {isEventSeries, needsDateAndTime, src};
  });
  console.log(data);
})()
  .catch(err => console.error(err))
  .finally(() => browser?.close());

输出:

{
  isEventSeries: 'False',
  needsDateAndTime: 'False',
  src: 'Veranstaltungen2/534be454-f064-42f4-a434-8530d8ad4a48'
}

尽可能避免使用元素句柄,它们很难使用。只需使用

$eval
$$eval
evaluate
提取数据即可。

page.$()
不会自动等待,这是必要的,因为该属性是动态添加到画布的,所以这基本上是不可能的,至少如果您要在
{waitUntil: "domcontentloaded"} 上使用最快的 
goto
 谓词的话
,你应该(链接的博客文章是我的)。

© www.soinside.com 2019 - 2024. All rights reserved.