我正在尝试从Puppeteer获取块列表的高度,但我无法在page.evaluate()
中选择我的块,因为它会抛出错误。
所以,我有这段代码:
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto(`data:text/html,${html}`);
for (let property in blockIds) {
if (blockIds.hasOwnProperty(property)) { console.log(property);
const height = await page.evaluate(property, () => {
return document.getElementById(property).offsetHeight;
});
console.log(property, height)
}
}
await browser.close();
})();
html
是字符串中的有效HTML页面。blockIds
是此类型的对象:{ 'block-id': null, 'block-id-2': null}
我的想法是获得所有块的高度,以便我可以获得此输出:
{'block-id': 123, 'block-id-2': 321}
但是当我运行这段代码时,我得到了以下输出 (注意 question-2 是我的blockId)
问题-2
(node:6338)UnhandledPromiseRejectionWarning:未处理的承诺拒绝(拒绝ID:1):错误:评估失败:ReferenceError:问题未定义 at:1:1
(node:6338)[DEP0018]弃用警告:不推荐使用未处理的拒绝承诺。将来,未处理的承诺拒绝将使用非零退出代码终止Node.js进程。
我真的不明白为什么这段代码不起作用,如果我直接在document.getElementById
内放置«question-2»,Puppeteer会给我正确的高度。
那么,我错过了什么?
答案 0 :(得分:0)
page.evaluate
的第一个参数传递,如Puppeteer文档中所示。https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#pageevaluatepagefunction-args
传递给page.evaluate
的任何参数也必须传递给您传递的函数。 page.evaluate((arg)=>{}, arg);
使用for...in
循环,该值未分配给property
,它将分配属性名称。要在for...in
循环中访问该值,您应该执行以下操作:blockIds[property]
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in
总结你得到:
await page.evaluate((property) => {
return document.getElementById(property)_.offsetHeight;
}, blockIds[property])
您可能需要考虑从for...in
循环切换到for...of
循环。这会将值赋给property
,从而允许您更简洁的循环体,因为它也会忽略从原型继承的属性,因此您可以省略.hasOwnProperty
检查,因为它不需要。
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of
这将导致:
for (let property of blockIds) {
//no need to check for .hasOwnProperty here
const height = await page.evaluate((property) => {
return document.getElementById(property).offsetHeight;
}, property); //no need to use blockIds[property] here
}