2017-09-23 148 views
0

我正在嘗試使用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。

我接近這個錯誤嗎?

+0

你'page.goto(URL)'調用似乎是錯誤的。 – nilobarp

+0

我按照https://github.com/GoogleChrome/puppeteer/blob/master/examples/custom-event.js中的示例首先公開該函數,然後轉到該頁面。另請注意,'await browser.close();'發生在應用程序加載後幾秒鐘內調用的回調函數中,所以它無關緊要。 移動'await page.goto(url);'並沒有使警告消失。 – hjm27

回答

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