How to capture a website screenshot with PhantomJS and save it as PNG
Capture a website as PNG with PhantomJS, set the viewport and clip area, and handle load failures. Includes a modern API alternative.
Use PhantomJS’s webpage module to open the URL, then call page.render('screenshot.png') from the page.open() callback. Save the script as capture.js and run phantomjs capture.js. Check the callback status before rendering so a failed load is not mistaken for a valid screenshot.
Legacy warning: PhantomJS development is suspended, and its GitHub repository is archived and read-only. Treat this as maintenance guidance for existing scripts; consider compatibility and security before adopting PhantomJS for a new system. PhantomJS project homepage · Archived repository.
1. Capture a website as a PNG
Install or locate a PhantomJS executable that works in your environment, then create capture.js:
var page = require('webpage').create();
page.open('https://example.com/', function (status) {
if (status !== 'success') {
console.error('Unable to load the page.');
phantom.exit(1);
return;
}
page.render('screenshot.png');
phantom.exit();
});
Run it from a shell:
phantomjs capture.js
The page.open() callback receives success or fail. Render only after success. The filename passed to page.render() is the render destination; use a .png filename for PNG output. See the official screen capture tutorial and page.open() API.
2. Set the viewport and capture rectangle
The viewport controls the headless browser’s visible page dimensions. clipRect selects the rectangle rendered into the output. Set them before opening the page:
var page = require('webpage').create();
page.viewportSize = { width: 1024, height: 768 };
page.clipRect = { top: 0, left: 0, width: 1024, height: 768 };
page.open('https://example.com/', function (status) {
if (status !== 'success') {
console.error('Unable to load the page.');
phantom.exit(1);
return;
}
page.render('screenshot.png');
phantom.exit();
});
These settings frame a 1024 × 768 rectangle. A viewport-sized capture does not automatically mean the entire length of a long page is included. Choose dimensions and a clip rectangle that suit the view you need. The official tutorial documents PNG, JPEG, GIF, and PDF render formats; this guide uses PNG.
3. Choose a reliable capture flow
- Confirm that the PhantomJS executable is available with
phantomjs --version. - Put the target URL in
page.open()and configure the viewport and clip rectangle before opening. - Wait for the asynchronous
page.open()callback. - Render only when the callback status is
success. - Exit with a nonzero status on failure so a calling script can detect the problem.
The status check protects against treating a failed navigation as a successful screenshot. The API’s documented callback statuses are success and fail. For command-line arguments and options, see the PhantomJS command-line reference.
4. Troubleshoot common problems
| Symptom | Likely cause | What to do |
|---|---|---|
phantomjs is not found |
The executable is not on the shell’s command path, or PhantomJS is not installed in this environment. | Check the installation and executable path. The official CLI invocation is phantomjs [options] somescript.js [arg1 ...]. |
| The page does not render | page.open() returned fail. |
Keep the status check, report the failure, and do not treat an output as valid. Check the URL and whether the target is reachable from the machine running PhantomJS. |
| The image has unexpected dimensions | The viewport or clip rectangle does not match the desired frame. | Set page.viewportSize and page.clipRect deliberately. The clip rectangle defines the captured area. |
| Behavior differs between runs or machines | Different PhantomJS executables or versions may be in use. | Run phantomjs --version and confirm which executable your script invokes. The official troubleshooting guide warns that multiple installed versions can conflict. |
| A TLS or certificate error occurs | The target’s certificate validation or TLS connection is failing. | Investigate the certificate and environment first. The CLI documents --ignore-ssl-errors, which changes certificate-error handling; do not use it as a routine fix. |
5. Performance, reliability, and cost
This capture runs through a legacy browser runtime, so compatibility and availability of a working executable depend on the environment; the cited sources do not establish binaries for every current operating system. Keep the script’s success check and make the caller inspect its exit code. The official project says development is suspended, and the repository is archived, so account for maintenance and security implications before relying on it in a new service.
The research sources provide no benchmark or current PhantomJS pricing information. Your practical costs depend on the machine and operations you use. If captures are part of a production workflow, consider whether maintaining the browser runtime and its dependencies is acceptable.
Or skip the browser setup
ScreenshotNeo is a website screenshot API and MCP server from Yorker Media. A GET request returns an image or PDF; its API accepts the parameter names other screenshot APIs use, which can make switching easier. See the ScreenshotNeo API docs.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com -o shot.webp
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://example.com"},
timeout=90,
)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://example.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
- Cookie banners are accepted and 60+ known consent platforms, newsletter popups, and chat widgets are removed before the shot; each step can be turned off.
- Bot checks, blank pages, timeouts, failed loads, and cache hits cost nothing. Response headers report the page verdict and whether the request was billed.
- An MCP server gives AI agents tools for screenshots, page information, and PDF capture.
- The free plan includes 1,000 screenshots each month with no card. Paid plans start at $5 for 3,000 screenshots; every feature is on every plan.
Sign up for ScreenshotNeo’s free plan to get 1,000 screenshots a month with no card.
FAQ
What command runs the script?
Save it as capture.js, then run phantomjs capture.js.
Does this capture a whole long page?
The viewport and clip rectangle determine the rendered frame. The documented example sets a fixed rectangle; it does not promise an automatic full-page capture.
Can I save another format?
The official capture tutorial names PNG, JPEG, GIF, and PDF as render formats. Use a PNG filename for this guide’s output.
Is PhantomJS suitable for a new project?
Its development is suspended and its repository is archived. Review those project status facts and your environment’s compatibility and security needs before choosing it.


