puppeteer在调用暴露函数后截取屏幕截图

时间:2017-09-23 04:33:35

标签: javascript node.js asynchronous puppeteer

我正在尝试使用puppeteer导航到某个页面,等待webapp达到特定状态,截取屏幕截图并退出。当SPA处于我想截取屏幕截图的状态时,它会调用一个函数。我很难绕过异步js代码。

我的代码如下:

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()做了一点点但是将它暴露给webapp的窗口是安全的。我只是尝试给出一个上面的最小脚本的例子仍然失败。

我正在使用node v8.5.0。

我接近这个错误吗?

1 个答案:

答案 0 :(得分:0)

我认为该函数有一些调用者,你不需要自己用它来调用它。

Imo,browser.close应该移动到最后并转到曝光函数之前。至于文档中的readFunction,如果返回一个promise,它将被等待。最后async / await是承诺的糖

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);
})();