【问题标题】:How do I go about taking screenshots of every dynamically loaded page using Express and Puppeteer?如何使用 Express 和 Puppeteer 截取每个动态加载的页面?
【发布时间】:2020-02-14 17:00:26
【问题描述】:

我正在创建一个应用程序,我想在其中生成 QR 码图片以及其他一些文本内容,这些内容将 [使用 qrcode 库] 动态生成。该二维码将在 PugJS 模板和 ExpressJS 的帮助下呈现到端点。我必须存储保存这个渲染屏幕的图片,我正在使用 Puppeteer 执行此操作。这在生成 一个 QR 码并拍摄快照或拍摄单个 QR 码的多个快照时效果很好。我正在寻找的是生成一个二维码,拍摄它的快照,然后生成下一个二维码,拍摄它的快照,等等。

我面临的问题是,由于 Puppeteer 驱动程序函数本质上是异步的,我认为我可以拍摄多个屏幕截图的唯一方法是,如果我将它放在 for 循环中,然后像代码中给出的那样执行它以下。但这不适用于较大的 i (=100) 值,因为我们实际上是在每次 i 迭代时创建一个无头镶边,并给出以下错误:

   (node:34536) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 exit listeners added. Use emitter.setMaxListeners() to limit
   (node:34536) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 SIGINT listeners added. Use emitter.setMaxListeners() to increase limit

我尝试将 for 循环放在 'get' express 方法之后和渲染之前以减少内存负载,我尝试在异步代码中更改执行流程。

   const express = require('express');
   const JsBarcode = require('jsbarcode');
   const { Canvas } = require("canvas");
   const app = express();
   const port = process.env.PORT || 3000;
   const QRCode = require('qrcode')
   const puppeteer = require('puppeteer');
   app.set('view engine', 'pug');
   app.use(express.static(__dirname + '/public'));

var renderdeet;

for (let i = 0; i < 5; i++){QRCode.toDataURL(process.env.QR_CODE_URL+'sku_type'+process.env.QR_CODE_SUFFIX+'item', function(err, url) {
        renderdeet = { item: 'ANYTHING'+i, packingDate:'17-10-2019', type: 'ABC', batch: 'COR01288C', net_qty: '50g', qrCode: url }
    }) 

    app.get('/generateLabel', (req, res) => {
        res.render('index', renderdeet);  
    }
    );
    (async ()=> {
        const browser = await puppeteer.launch();
        const page = await browser.newPage();
        await page.goto('http://localhost:5150/generateLabel');
        const dimensions = await page.evaluate(() => {
            return {
              width: document.body.clientWidth,
              height: document.body.clientHeight,
              deviceScaleFactor: 1
            };
          });
          await page.setViewport(dimensions)
        await page.evaluate(() => document.body.style.background = 'transparent');
        await page.screenshot({path: 'outputs/example'+i+'.png', omitBackground: true});
        await browser.close();
      })();
}

    app.listen(port, () => {
    console.log(`listening on port ${ port }`);
    });

预期结果会在输出文件夹中获得 100 张图片,每张图片都有不同的 QR 码和标签细节。

实际结果,要么是内存错误(使用这种方法),要么是因为puppeteer函数的问题根本没有截图

【问题讨论】:

    标签: node.js express asynchronous puppeteer


    【解决方案1】:

    您正在 forloop 中创建和执行一个函数,您需要做的是在 for 循环之外创建异步函数,然后执行是在 for 循环中使用 await。

    其次,你应该在开始循环之前打开浏览器一次,然后在for循环中使用页面实例。

    请确保在循环结束后关闭浏览器。

    结构如下:

    {libraries}
    
    {Start Browser and save it in a variable}
    
    {loopstart}
        await myfunc(page)
    {loopend}
    
    {close browser}
    
    {async myfun(page){}}
    

    【讨论】:

    • 嗨,我以前试过这个,但我无法让它执行。你能用实际代码替换 {Start Browser and save it in a variable} {loopstart} await myfunc(page) {loopend} {close browser} {async myfun(page){}} 吗?
    猜你喜欢
    • 1970-01-01
    • 2018-12-10
    • 2020-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-29
    相关资源
    最近更新 更多