我只是想从网站上删除一些东西。
在尝试访问元素上的属性值时遇到问题。该值返回
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 '
});
如何正确访问该属性?
我不确定您最终想要获取什么数据,所以这可能是一个 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
谓词的话,你应该(链接的博客文章是我的)。