puppeteer在公开函数被调用后拍摄屏幕截图
问题描述:
我正在尝试使用puppeteer导航到页面,等待webapp达到特定状态,截屏并退出。当SPA处于我想截图的状态时,它会调用一个函数。我很难绕过异步JS代码。puppeteer在公开函数被调用后拍摄屏幕截图
我的代码如下:
const puppeteer = require('puppeteer');
const url = 'http://example.com/';
const width = 300;
const height = 250;
const path = '/vagrant/tmp/screenshot.jpg';
async function takeScreenshoot(url, width, height, path) {
"use strict";
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.setViewport({width: width, height: height});
await page.exposeFunction('interestingFunction', (async data => {
console.log('Interesting function has been called. Taking a screenshot now.');
await page.screenshot({path: path});
await browser.close();
}));
await page.goto(url);
}
(async() => {
"use strict";
await takeScreenshoot(url, width, height, path);
})();
但是当我打电话screenshot.js
,我得到一个未处理的承诺,说警告“会议闭幕最有可能的页面已被关闭。”
node --trace-warnings screenshot.js
Interesting function has been called. Taking a screenshot now.
(node:2572) Error: Protocol error (Runtime.evaluate): Session closed. Most likely the page has been closed.
at Session.send (/vagrant/node_modules/puppeteer/lib/Connection.js:167:29)
at Page._onConsoleAPI (/vagrant/node_modules/puppeteer/lib/Page.js:296:20)
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:188:7)
(node:2572) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
at emitWarning (internal/process/promises.js:78:15)
at emitPendingUnhandledRejections (internal/process/promises.js:95:11)
at process._tickCallback (internal/process/next_tick.js:189:7)
如果我删除线18 await browser.close()
,没有警告,但是脚本永远不会完成。
现在,interstingFunction()
做了一些更多,但它是安全的暴露给web应用程序的窗口。我只是试图举一个上面的小脚本的例子,但仍然失败。
我正在使用节点v8.5.0。
我接近这个错误吗?
答
我假设有一些函数的调用者,你不需要自己用评估来调用它。
Imo,browser.close应该被移动到最后并且去暴露函数之前。至于在文档中阅读exposeFunction如果返回一个承诺它将被等待。到底异步/等待是糖承诺
await page.exposeFunction('interestingFunction', (async data => {
console.log('Interesting function has been called. Taking a screenshot now.');
await page.screenshot({path: path});
await browser.close();
}));
await page.goto(url);
这就是我的全部例子
const url = 'http://example.com/';
const width = 300;
const height = 250;
const path = './screenshot.jpg';
async function takeScreenshoot(url, width, height, path) {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto(url, {waitUntil: 'load'});
await page.exposeFunction('jjj', (async() => {
console.log('Interesting function has been called. Taking a screenshot now.');
return await page.screenshot({path: path});
}));
await page.evaluate(async() => {
const myHash = await window.jjj();
});
await browser.close();
}
(async() => {
await takeScreenshoot(url, width, height, path);
})();
+0
非常感谢您的时间!是的,我自己并没有调用“interestingFunction()”。不幸的是,您提出的解决方案会返回而无需等待公开的函数至少被调用一次,因此不会进行任何截图。这就是在原始示例中试图关闭浏览器内的浏览器的原因。 – hjm27
你'page.goto(URL)'调用似乎是错误的。 – nilobarp
我按照https://github.com/GoogleChrome/puppeteer/blob/master/examples/custom-event.js中的示例首先公开该函数,然后转到该页面。另请注意,'await browser.close();'发生在应用程序加载后几秒钟内调用的回调函数中,所以它无关紧要。 移动'await page.goto(url);'并没有使警告消失。 – hjm27