Return String

Puppeteer: Taking Screenshots

Updated 2020-07-21

Learn to take screenshots of websites using Puppeteer and JavaScript with this beginner friendly tutorial. By the end of this tutorial you will be able take screenshots at different resolutions and understand the important difference between the browser window and viewport.

Project Setup

We learned how to set up a project using Puppeteer in part 1 of this series. Make sure you have created a new project and installed puppeteer with npm install puppeteer in a terminal from your project folder.

Your package.json file should look something like this:

{
    "name": "puppeteer-taking-screenshots",
    "version": "1.0.0",
    "dependencies": {
        "puppeteer": "^5.0.0"
    }
}

Let us create a file named scraper.js in our project folder and add the code required to launch a browser as well as navigating to a URL. This was described in part 1 of this series.

// Require the puppeteer library
const puppeteer = require('puppeteer');

// To use await we wrap our code in an async function
async function scrape() {
    // Create the browser without headless mode
    const browser = await puppeteer.launch({ headless: false });

    // Create a new page (tab) in the browser
    const page = await browser.newPage();

    // Navigate to a website
    await page.goto('https://returnstring.com');

    // CODE USING THE BROWSER HERE

    // Close the browser
    await browser.close();
}

// Run our function
scrape().catch(console.error);

Full Page Screenshot

To take a screenshot with Puppeteer we can use page.screenshot(OPTIONS). The options you pass in to screenshot is an object. The options object must have a path attribute with a filename. For our purposes, let us simply save it as page-screenshot.jpg in our project folder.

await page.screenshot({ path: `page-screenshot.jpg` });

Adding this line after we have waited for Puppeteer to goto our URL should generate a screenshot in your project folder. This screenshot will likely be in 800x600 resolution.

Sizing Screenshots

We may want to change the size of the browser to take screenshots at different resolutions. We can change both the viewport and the window size through the launch options we pass in to puppeteer.launch.

Viewport Or Window

When you use a browser in your everyday life, your window size and viewport scale automatically at the same time. When you maximize your window, the viewport scales to fit inside the window. You can think of the viewport as the actual area the website is rendered. The window includes your address bar, home buttons and the scroll bar. The viewport includes none of those things, only the actual area the website is in.

To change our screenshot size we must resize the viewport. We would only want to scale up the window alongside the viewport if we are debugging with headless: false and need to see what is happening ourselves.

Viewport Sizing

We can resize the viewport by adding a defaultViewport object to our launch options we pass in to puppeteer.launch. Our defaultViewport object should contain a height and a width property.

// Create browser with options object
const browser = await puppeteer.launch({
    // Set viewport size
    defaultViewport: { width: 1920, height: 1080 },

    // Disable headless mode for debugging
    headless: false
});

This will launch a browser with a 1080p resolution for the viewport. Your window size will remain the same when your browser opens, however your screenshot should now be 1920x1080.

Window Sizing

Sizing the window of the browser is rarely used outside of debugging your code. Resizing the window will not resize the viewport like it will in a normal browser.

To change the window size at launch we can pass an array of strings called args to puppeteer.launch. The args should match the arguments you can use when launching the browser from a terminal. For our Chromium browser, we can set the window size with --window-size=WIDTH,HEIGHT.

// Create browser with options object
const browser = await puppeteer.launch({
    // Set window size
    args: ['--window-size=1920,1080'],

    // Disable headless mode for debugging
    headless: false
});

This will launch a browser with a window size of 1920x1080. If you add this to our current script without resizing the viewport, you can observe the clear difference between viewport and window size. You should also note your screenshot is unaffected by the window resizing.

Quick Cleanup

As we are adding more launch options to puppeteer.launch we should probably move the options object into it's own variable to make our code more readable.

// Options for launching the browser
const launchOptions = {
    // Set viewport size
    defaultViewport: { width: 1920, height: 1080 },

    // Set window size
    args: ['--window-size=1920,1080'],

    // Disable headless mode for debugging
    headless: false
};

Remember to pass this object in to puppeteer.launch instead of our inline object.

const browser = await puppeteer.launch(launchOptions);

The Code

Setting both window and viewport size to 1080p and taking a screenshot would look like this.

// Require the puppeteer library
const puppeteer = require('puppeteer');

// Options for launching the browser
const launchOptions = {
    // Set viewport size
    defaultViewport: { width: 1920, height: 1080 },

    // Set window size
    args: ['--window-size=1920,1080'],

    // Disable headless mode for debugging
    headless: false
};

// To use await we wrap our code in an async function
async function scrape() {
    // Create the browser without headless mode
    const browser = await puppeteer.launch(launchOptions);

    // Create a new page (tab) in the browser
    const page = await browser.newPage();

    // Navigate to a website
    await page.goto('https://returnstring.com');

    // Taking a screenshot
    await page.screenshot({ path: `page-screenshot.png` });

    // Close the browser
    await browser.close();
}

// Run our function
scrape().catch(console.error);

Next Steps

You have successfully automated taking screenshots at different resolutions and learned about different options for launching puppeteer.

Continue to part 3 of this series to learn more about clicking, typing and waiting with Puppeteer.

If you are hooked and want to learn more about taking screenshots you can look forward to an article on Taking Screenshots for Stakeholders I am currently writing.