Let’s set the scene why you would require to take a screenshot of website. A couple years ago, I was working for an intellectual property law firm who’s clients included some of the world largest software houses. I was working as a developer and my requirements was to scrap known website where the clients software were more likely to be distributed illegally, ie. torrents site.

This was back in ’09 and the initial PoC save the pages HTML which required to opened in a frame in order to be viewed. The application did not have a UI as the results was sent to Salesforce case management system. I recently came across a project trying to do the same thing but with illegal use of photos.

I decided to take a look at how this could be done but not only saving the HTML of the source page but to take a screenshot of what it looked at the time of crawling. There are many services now offers API to allow your application to take screenshots of website. But there is a simpler easier solution;

Introducing Firefox Headless Mode

Headless mode is a very useful way to run Firefox. Just as it might sound, Firefox is run as normal, minus any visible UI components visible. Though not so useful for surfing the web, it comes into its own with automated testing.

Firefox Headless mode allows to run Firefox as a background service. The headless mode as a

-screenshot
parameter which allows the browser to take a full page screenshot of a given URL. The following simple command would take a screenshot in Firefox:

/path/to/firefox -headless -screenshot https://developer.mozilla.com
You can omit the -headless flag when using the -screenshot flag as follow
/path/to/firefox -screenshot https://developer.mozilla.com
Please see Firefox Dev page for a list of all available options.

Take a screenshot from Java

A prerequisite is to make sure that Firefox is installed and accessible from your Java application.

The java code will execute the external Firefox process. I’m using Java 11 and the ProcessBuilder API but you can do the same with the Runtime API. The ProcessBuilder API gives you more control over the executed process.

It is important to remember that you can only have a single instance of Firefox running on your system. In a multi-threaded environment, you will control access to this process.

Here is a simple example of running Firefox in headless mode and taking a screenshot from Java; this is run from a MacOS.


package com.kiktronik.websitescreengraber;

import java.io.IOException;

/**
 *
 * @author Armel Nene
 */
public class Screenshot {
    
    public static void main(String[] args) throws IOException{
        Process p = new ProcessBuilder("/Applications/Firefox.app/Contents/MacOS/firefox", "--headless", "--screenshot", "armelnene.png", "https://www.armelnene.co.uk").start();
        System.out.println("Process ID: " + p.info());
    }
    
	}
	
I hope this would help you in your next project. Happy coding.