1

I have used Nodejs and try to takes the screenshot of given URL. It works perfect on local but After deploy to Azure have problems on create puppeteer.

Code

exports.getScreenShot = async function (req, res) {
    const requesturl = req.param('url');
    if (!requesturl) {
        return res.send(400, 'Missing url');
    }
    const parsedUrl = url.parse(requesturl);
    if (!parsedUrl.protocol) {
        return res.send(400, 'Invalid url, missing protocol');
    }
    if (!parsedUrl.hostname) {
        return res.send(400, 'Invalid url, missing hostname');
    }

    const options = {
        'width': req.param('width'),
        'height': req.param('height'),
        'delay': req.param('delay'),
        'userAgent': req.param('userAgent'),
        'full': (req.param('full') === 'true')
    };

    options.width = options.width || 1024;
    options.height = options.height || 768;
    options.delay = options.delay || 200;    
    const browser = await puppeteer.connect({
        browserWSEndpoint: 'wss://chrome.browserless.io/'
    });

    let page = await browser.newPage();
    await page.goto(requesturl);
    await page.waitFor(parseInt(options.delay));
    let imageName = parsedUrl.hostname.replace(/\W/g, '_');
    let pathName = parsedUrl.pathname.replace(/\W/g, '_').replace(/_$/, '');
    if (pathName) {
        imageName += pathName;
    }
    imageName = `${imageName}.png`;
    var tempPath = temp.path({ suffix: '.png' });
    await page.setViewport({ width: parseInt(options.width), height: parseInt(options.height) });
    await page.screenshot({
        path: tempPath,
        fullPage: options.full
    });
}
Nayeem Mansoori
  • 821
  • 1
  • 15
  • 41

2 Answers2

6

Refer to the SO Tag Info for puppeteer, as below.

Puppeteer is a Node library which provides a high-level API to control headless Chrome or Chromium over the DevTools Protocol. It can also be configured to use full (non-headless) Chrome or Chromium.

Whatever Chrome or Chromium with headless or non-headless, they all require GDI support. However, on Azure App Services on Windows, it conflicts with Win32k.sys (User32/GDI32) Restrictions, as the figure below.

enter image description here

And other frameworks like PhantomJS/Selenium also be restricted by it, see below.

enter image description here

So you can not use puppeteer within Azure WebApp on Windows. The workaround solution is to use Azure VM or Azure WebApp on Linux. Essentially, this issue is duplicated with your other SO thread Chrome driver is not working on azure web apps.

Hope it helps.

Peter Pan
  • 23,476
  • 4
  • 25
  • 43
  • 3
    I believe it doesn't work on Azure WebApp on linux either. If it does for you, that is great news. Would you be willing to share more details about your setup on linux? – Marko Prcać Jul 04 '20 at 21:25
  • 1
    Can confirm that this does not work on linux either as @MarkoPrcać suggested. – Splitty Dec 21 '20 at 17:15
3

How to run Headless Chrome in Azure Cloud Service or Azure Functions

Replace puppeteer.launch with puppeteer.connect. See the code below:

const browser = await puppeteer.connect({ browserWSEndpoint: 'wss://chrome.browserless.io/' });
obertuccini
  • 83
  • 1
  • 4
Chakresh Sahu
  • 321
  • 2
  • 5
  • Browserless.io is pretty cool, it's free for a small number of requests/per day and then has usage based pricing options. This was a great solution for my use case. – patrickbadley May 26 '21 at 23:56