Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Repair Windows errors before they cause bigger problemsFix Now →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Use casper.captureSelector(targetFile, selector) when the desired screenshot is a DOM element, or set PhantomJS’s page.clipRect and call page.render() when you need a fixed coordinate rectangle. For HTML rather than an image, use CasperJS getHTML(selector, outer). PhantomJS’s page.content returns the complete main-frame document, not a selector-scoped fragment.
The examples below cover both jobs, asynchronous pages, coordinate measurement, output formats, and the limitations of this legacy stack.
Choose the operation before writing code
“Capture part of a page” can mean either extracting markup or rendering pixels. Pick the API that matches the output you need.
| Goal | API | Targeting method | Result |
|---|---|---|---|
| Screenshot of one element | CasperJS captureSelector() |
CSS selector | Raster image of the selector’s area |
| Screenshot of a fixed region | CasperJS capture() or PhantomJS page.clipRect |
top, left, width, height |
Raster image of that rectangle |
| Inner or outer HTML for one element | CasperJS getHTML() |
CSS selector | Markup string |
| Entire main-frame HTML | PhantomJS page.content |
No selector filtering | Complete document markup |
| Current response body, including non-HTML | CasperJS getPageContent() |
No DOM selector | Response content as a string |
A selector is usually safer for a component that moves with responsive layout. A rectangle is appropriate for a chart viewport or another deliberately fixed region.
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallOutdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware match#1 Best Overall
Capture one element with CasperJS
captureSelector() accepts a destination filename, a CSS selector, and optional image settings. Wait for the element before capturing so a client-side application has time to insert it.
var casper = require('casper').create();
casper.start('https://example.com', function () {
this.waitForSelector('#article', function () {
this.captureSelector('article.png', '#article');
});
});
casper.run();
This saves the area occupied by #article to article.png. Replace the selector with a class, attribute selector, or any other CSS selector supported by the PhantomJS-era browser engine.
Capture with image options
CasperJS passes image options through to PhantomJS. For JPEG output, specify a JPEG format and a quality value from 1 through 100.
var casper = require('casper').create();
casper.start('https://example.com', function () {
this.waitForSelector('.hero', function () {
this.captureSelector('hero.jpg', '.hero', {
format: 'jpg',
quality: 85
});
});
});
casper.run();
Use PNG when you need crisp text or transparency; use JPEG when a smaller photographic file matters. The actual rendering still depends on the legacy PhantomJS engine and the page’s loaded state.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Rank #2
Capture a fixed rectangle with PhantomJS
PhantomJS separates the browser viewport from the part rendered to an image. Set viewportSize first, open the page, then assign clipRect and render.
var page = require('webpage').create();
page.viewportSize = { width: 1280, height: 900 };
page.open('https://example.com', function (status) {
if (status !== 'success') {
phantom.exit(1);
}
page.clipRect = {
top: 120,
left: 80,
width: 640,
height: 420
};
page.render('partial.png');
phantom.exit();
});
The rectangle is measured from the rendered viewport’s top-left corner. In this example, the output begins 80 pixels from the left edge and 120 pixels from the top, and is 640 by 420 pixels.
The same rectangle through CasperJS
CasperJS provides capture(), a convenience wrapper around PhantomJS rendering. Its documented signature is capture(targetFile, clipRect, imgOptions).
var casper = require('casper').create();
casper.start('https://example.com', function () {
this.capture('partial.png', {
top: 100,
left: 100,
width: 500,
height: 400
});
});
casper.run();
Use this form when the crop is intentionally coordinate-based rather than tied to a particular element.
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Clear out junk files and repair common Windows errors3Scan for outdated or missing drivers - takes under a minuteMeasure a moving element before capturing it
Responsive layouts, banners, and fonts can move an element after navigation. DOM measurements must run in the page context, so use CasperJS evaluate() or thenEvaluate(). Return the element’s bounding rectangle and pass it to capture().
var casper = require('casper').create();
casper.start('https://example.com', function () {
this.waitForSelector('#chart', function () {
var rect = this.evaluate(function () {
var element = document.querySelector('#chart');
var box = element.getBoundingClientRect();
return {
top: box.top,
left: box.left,
width: box.width,
height: box.height
};
});
this.capture('chart.png', rect);
});
});
casper.run();
Set the viewport before navigation when coordinates must be reproducible. A different viewport can trigger a different breakpoint, changing both the element’s dimensions and its position.
Extract only part of the page HTML
For markup, do not render a screenshot and do not use page.content as a substitute for a selector query. CasperJS’s getHTML(selector, outer) returns the selected element’s inner HTML by default. Pass true for the element itself plus its contents.
var casper = require('casper').create();
casper.start('https://example.com', function () {
this.waitForSelector('#article', function () {
this.echo(this.getHTML('#article')); // inner HTML
this.echo(this.getHTML('#article', true)); // outer HTML
});
});
casper.run();
When the response is not an HTML document
If the URL returns JSON or another response body rather than a rendered document, use getPageContent() and parse the returned string. It is a response-content operation, not a selector-scoped DOM extraction.
What PhantomJS exposes directly
page.content exposes the whole main-frame HTML. It is useful when you need the complete document after scripts have modified it, but it does not accept a CSS selector. To obtain a fragment, query the DOM in evaluate() or use CasperJS getHTML().
Rank #4
Wait for the page that will actually be captured
A successful navigation callback does not guarantee that a framework has finished inserting the target node. Wait for the selector and, where necessary, for visibility or a page-specific condition before extracting or rendering.
- Use
waitForSelector()for a node that appears asynchronously. - Use CasperJS visibility and waiting helpers when the node exists but is initially hidden.
- Use
evaluate()orthenEvaluate()to inspect dimensions or application state in the page context. - Only call
captureSelector(),capture(), orrender()after the content and its layout are ready.
If images are lazy-loaded, wait for the page’s own condition that indicates they have been inserted and displayed. A selector existing in the DOM is not proof that its fonts, images, or client-rendered text have finished painting.
Output formats and rendering limits
PhantomJS render() documents PDF, PNG, JPEG, BMP, PPM, and GIF output; GIF support depends on the Qt build. PNG and JPEG quality options are available, and CasperJS forwards format and quality settings through its capture methods.
For a partial image, the important rendering inputs are the viewport, the crop rectangle or selector, and the page state at capture time. Keep those inputs stable when producing visual diffs or repeatable reports.
Best Value
Troubleshooting partial captures
| Symptom | Likely cause | Correction |
|---|---|---|
| The file contains the whole page instead of one component | The script called page.render() without setting clipRect, or used page.content expecting a fragment. |
Use captureSelector() for a DOM element, or set clipRect before rendering. Use getHTML() for markup. |
| The selector capture is blank or incomplete | The target was not present, visible, or populated when capture ran. | Wait for the selector and the page-specific ready condition before capturing. |
| The crop is shifted | Viewport dimensions or responsive breakpoints differ from the values used to calculate the rectangle. | Set viewportSize before opening the page, or measure the element with getBoundingClientRect() immediately before capture. |
| Coordinates work on one page state but not another | Dynamic content changed the layout. | Prefer a selector capture, or recompute the rectangle in evaluate() after the dynamic content appears. |
| HTML extraction returns unexpected content | The URL returned JSON or another non-HTML response, or the wrong API was used. | Use getPageContent() for the response body; use getHTML() only when querying rendered DOM markup. |
| The script exits before writing an image | The navigation status was not successful, or the script called phantom.exit() before the callback finished. |
Check the status in the page.open() callback and exit only after render() completes. In CasperJS, keep the capture inside the queued step and call run(). |
| Modern site styling differs from a current browser | PhantomJS uses an old browser engine. | Confirm that the legacy rendering is acceptable for your target, or move the capture to a maintained browser-based service. |
Reliability and maintenance considerations
Control layout inputs
For repeatable images, fix the viewport, use a stable URL, wait for asynchronous content, and choose a selector rather than hard-coded coordinates whenever the component can move. Record the rectangle and viewport with the output if another process will consume the image.
Keep extraction separate from rendering
HTML extraction is text processing and can preserve markup for downstream parsing. Image capture depends on layout, fonts, image loading, and paint timing. Treat failures in those paths differently: a valid HTML string does not prove that a visual capture is ready.
Plan for the legacy runtime
CasperJS’s repository states that “CasperJS is no longer actively maintained.” It recommends the project mainly when existing PhantomJS 1.9 production tests must continue, and releases through 1.1-beta3 do not support PhantomJS 2.0 and newer. Verify the exact PhantomJS and CasperJS versions in your environment before deployment; do not assume a script written for one combination works with another.
Free tools Windows power users keep installed
One-click scans. No signup required.
Or skip the browser setup
If you need a maintained HTTP interface instead of installing PhantomJS and CasperJS, ScreenshotNeo returns a screenshot or PDF from one request. It can capture a CSS-selected element, full pages, custom viewports, and many other options without requiring a local browser process.
See the ScreenshotNeo API documentation for all parameters. This cURL request saves a WebP image:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
The equivalent Python request is:
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
timeout=90,
)
open("shot.webp", "wb").write(r.content)
And in Node.js:
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
ScreenshotNeo accepts cookie and consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each cleanup step can be disabled. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed as clean shots, and response headers identify the page verdict and billing result. Its MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients.
Plans for occasional and automated work
| Plan | Allowance | Price |
|---|---|---|
| Free | 1,000 shots per month | $0, no card |
| Starter | 3,000 shots | $5 |
| Growth | 15,000 shots | $15 |
| Pro | 60,000 shots | $39 |
| Scale | 250,000 shots | $99 |
| Business | 1,000,000 shots | $249 |
Every feature is included on every plan, and yearly billing provides two months free. You can sign up for the free plan with 1,000 screenshots a month and no card, then move to paid usage starting at $5 for 3,000 shots.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

