Сделайте скриншоты для списка URL, используя Puppeter.js - PullRequest
0 голосов
/ 04 мая 2018

Предположим, у меня есть список URL-адресов или полный путь к файлам SVG, и теперь я хочу сделать снимок экрана для каждого из URL-адресов, один за другим.

Вот тестовый код, который я использую для создания снимков экрана один за другим, но он не работает должным образом!

Этот код только один раз запускает безголовый экземпляр страницы Chrome для всех URL-адресов, а node.js выдает эту ошибку

(узел: 3412) MaxListenersExceededWarning: Возможная память EventEmitter обнаружена утечка. Добавлено 11 прослушивателей lifecycleevent. использование emitter.setMaxListeners () для увеличения лимита

Но я хотел сделать скриншоты один за другим.

'use strict';

const fs        = require('fs');
const glob      = require('glob');
const validUrl  = require("valid-url")
const puppeteer = require('puppeteer');
const devices   = require('puppeteer/DeviceDescriptors');
const iPhone    = devices['iPhone 6'];

/**
 * Loading Application Config
 */
const inputUrl = 'http://www.google.com';

/**
 * Using Puppeteer.js
 */
console.log('-- Trying to Launch Puppeteer');
const browser = puppeteer.launch({
    headless: true
}).then(function(browserObj)
{
    console.log('-- Trying to Open New Page');
    browserObj.newPage().then(function(pageObj)
    {
        async function closeHeadlesssChrome(browserObj) {
            console.log('-- Trying to Close Chome Headless Window');
            await browserObj.close();
        }

        async function setChromeViewport(pageObj) {
            console.log('-- Trying to Update page viewPort');
            await pageObj.setViewport({
                width: 1366,
                height: 738,
                deviceScaleFactor: 1,
                isMobile: false,
                hasTouch: false,
                isLandscape: false
            });
        }

        var takeScreenshot = async function(pageObj, srcUrl) {
            console.log('-- Trying to Load Web Page ' + srcUrl);
            await pageObj.goto(srcUrl);

            console.log('-- Trying to Take Screenshot');
            await pageObj.screenshot({
                path: srcUrl + '.png',
                clip: {
                    x: 0,
                    y: 0,
                    width: 795,
                    height: 1125
                }
            })
        }


        // Input or Source Url
        const inputUrl = "C:/Users/ssp/Music/BR PUBLIC INTER COLLEGE";
        var matchedFiles = [];

        // Check if given Url/Path exists
        if (fs.existsSync(inputUrl)) 
        {
            const inputUrlObj = fs.statSync(inputUrl);
            if (inputUrlObj.isDirectory()) 
            {
                matchedFiles = glob.GlobSync(inputUrl + '/**/*.svg').found;
            } 
            else if (inputUrlObj.isFile()) 
            {
                matchedFiles.push(inputUrl );
            }
        } 
        else 
        {
            console.log('-- Input Url not exists')
            return closeHeadlesssChrome(browserObj);
        }

        setChromeViewport(pageObj);

        matchedFiles.map(function(srcUrl){
            takeScreenshot(pageObj, srcUrl);
        });
    });
});

Спасибо

1 Ответ

0 голосов
/ 04 мая 2018

Используйте for..of с async-await вместо .map. .map не приостанавливает выполнение, но await будет.

browserObj.newPage().then(async function(pageObj) { // <-- turn the main function into async function
 // ... many lines later
 for(let srcUrl of matchedFiles){
  await takeScreenshot(pageObj, srcUrl);
 }

Примечание: поскольку все ваши функции независимы друг от друга, возможно, вы можете переместить их за пределы блока и объявить их перед вызовом browserObj.newPage ()

Вот переработанный код, простите, если что-то не так, но вы поняли.

"use strict";

const fs = require("fs");
const glob = require("glob");
const validUrl = require("valid-url");
const puppeteer = require("puppeteer");
const devices = require("puppeteer/DeviceDescriptors");
const iPhone = devices["iPhone 6"];

/**
 * Loading Application Config
 */
const inputUrl = "http://www.google.com";

/**
 * Controller functions
 */

async function closeHeadlesssChrome(browserObj) {
  console.log("-- Trying to Close Chome Headless Window");
  await browserObj.close();
}

async function setChromeViewport(pageObj) {
  console.log("-- Trying to Update page viewPort");
  await pageObj.setViewport({
    width: 1366,
    height: 738,
    deviceScaleFactor: 1,
    isMobile: false,
    hasTouch: false,
    isLandscape: false
  });
}

var takeScreenshot = async function(pageObj, srcUrl) {
  console.log("-- Trying to Load Web Page " + srcUrl);
  await pageObj.goto(srcUrl);

  console.log("-- Trying to Take Screenshot");
  await pageObj.screenshot({
    path: srcUrl + ".png",
    clip: {
      x: 0,
      y: 0,
      width: 795,
      height: 1125
    }
  });
};

function getURLList() {
  // Input or Source Url
  const inputUrl = "C:/Users/ssp/Music/BR PUBLIC INTER COLLEGE";
  var matchedFiles = [];

  // Check if given Url/Path exists
  if (fs.existsSync(inputUrl)) {
    const inputUrlObj = fs.statSync(inputUrl);
    if (inputUrlObj.isDirectory()) {
      matchedFiles = glob.GlobSync(inputUrl + "/**/*.svg").found;
    } else if (inputUrlObj.isFile()) {
      matchedFiles.push(inputUrl);
    }
    return matchedFiles;
  }
}

/**
 * Using Puppeteer.js
 */

(async () => {
  // get url list
  const matchedFiles = getURLList();
  if (!matchedFiles) {
    console.log("-- Input Url not exists");
    // if there is no url, then no need to even launch the browser and waste resources
    return;
  }

  console.log("-- Trying to Launch Puppeteer");
  const browserObj = await puppeteer.launch({
    headless: true
  });

  console.log('-- Trying to Open New Page');
  const pageObj = await browserObj.newPage();

  console.log('-- Change Viewport');
  await setChromeViewport(pageObj);

  console.log('-- Run thru the url list');
  for (const srcUrl of matchedFiles) {
    await takeScreenshot(pageObj, srcUrl);
  }
})();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...