Free tools Windows power users keep installed
One-click scans. No signup required.
If Selenium cannot create a screenshot, first separate capture from file writing: save to an absolute .png path, check the Boolean result, and verify that a non-empty file exists. If the file is valid but the image is blank, clipped, or stale, investigate browser state and screenshot scope. PhantomJS itself is a maintenance risk: its project says development is suspended, and Selenium deprecated its driver in favor of headless Chrome or Firefox.
Use a diagnostic save pattern first
Selenium’s Python WebDriver exposes save_screenshot(path) and the equivalent get_screenshot_as_file(path). The methods save the current window as a PNG and return True on success or False when file I/O fails, according to the Selenium Python WebDriver API. Treat the return value as a test assertion rather than ignoring it.
from pathlib import Path
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
out = Path("/absolute/path/to/artifacts/page.png")
out.parent.mkdir(parents=True, exist_ok=True)
options = Options()
options.add_argument("--headless")
driver = webdriver.Chrome(options=options)
try:
driver.get("https://example.com")
ok = driver.save_screenshot(str(out))
if not ok:
raise RuntimeError("WebDriver reported a screenshot I/O failure")
if not out.exists() or out.stat().st_size == 0:
raise RuntimeError(f"Missing or empty screenshot: {out}")
finally:
driver.quit()
Use the real absolute path for your operating system and ensure the process can write to its parent directory. Selenium’s API recommends a full path and a .png suffix. A successful save only proves that bytes were written; it does not prove that the page was ready or that the image contains the area you expected.
When save_screenshot returns False or creates no file
Check the path and directory
- Print the resolved path:
print(out.resolve()). - Create the directory before starting the browser, as in the example.
- Check permissions, container volume mounts, read-only workspaces, and available disk space.
- Avoid relative paths whose working directory changes between local runs and CI.
- Keep the filename’s
.pngsuffix; do not silently rename a PNG to another format.
Check the Boolean and the filesystem independently
Log both ok and the file’s size. If the method returns False, focus on local I/O first. If it returns True but the file is absent or zero bytes, inspect the environment for cleanup jobs, incorrect path mapping, or a process writing to a different filesystem than the one you are checking.
#1 Best Overall
- CRISP CLARITY: This 23.8″ Philips V line monitor delivers crisp Full HD 1920x1080 visuals. Enjoy movies, shows and videos with remarkable detail
- INCREDIBLE CONTRAST: The VA panel produces brighter whites and deeper blacks. You get true-to-life images and more gradients with 16.7 million colors
- THE PERFECT VIEW: The 178/178 degree extra wide viewing angle prevents the shifting of colors when viewed from an offset angle, so you always get consistent colors
- WORK SEAMLESSLY: This sleek monitor is virtually bezel-free on three sides, so the screen looks even bigger for the viewer. This minimalistic design also allows for seamless multi-monitor setups that enhance your workflow and boost productivity
- A BETTER READING EXPERIENCE: For busy office workers, EasyRead mode provides a more paper-like experience for when viewing lengthy documents
Separate browser capture from file writing
To determine whether WebDriver captured an image at all, use the byte or Base64 APIs documented in the same API reference:
png_bytes = driver.get_screenshot_as_png()
if not png_bytes:
raise RuntimeError("WebDriver returned no image bytes")
Path("/absolute/path/to/artifacts/raw.png").write_bytes(png_bytes)
# Alternatively:
encoded = driver.get_screenshot_as_base64()
print(f"Base64 characters: {len(encoded)}")
If bytes are returned but the file helper fails, the problem is in path or filesystem handling. If no bytes are returned, investigate the browser, driver, session, and page state.
Fix screenshots that are blank, stale, or visually wrong
Wait for the state your application needs
driver.get(url) waits for the page-load event, but modern applications may still be fetching data, decoding lazy images, running animations, or rendering after that event. Wait for a page-specific condition rather than adding an arbitrary long sleep.
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
wait = WebDriverWait(driver, 30)
wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "main")))
# Use a selector that proves the data or component you need is ready.
driver.save_screenshot(str(out))
Before capture, log driver.current_url, driver.title, and the presence or text of the target element. This catches redirects, authentication pages, error routes, and selectors that never matched.
Rank #2
- CRISP CLARITY: This 22 inch class (21.5″ viewable) Philips V line monitor delivers crisp Full HD 1920x1080 visuals. Enjoy movies, shows and videos with remarkable detail
- 100HZ FAST REFRESH RATE: 100Hz brings your favorite movies and video games to life. Stream, binge, and play effortlessly
- SMOOTH ACTION WITH ADAPTIVE-SYNC: Adaptive-Sync technology ensures fluid action sequences and rapid response time. Every frame will be rendered smoothly with crystal clarity and without stutter
- INCREDIBLE CONTRAST: The VA panel produces brighter whites and deeper blacks. You get true-to-life images and more gradients with 16.7 million colors
- THE PERFECT VIEW: The 178/178 degree extra wide viewing angle prevents the shifting of colors when viewed from an offset angle, so you always get consistent colors
Confirm the screenshot scope
A normal driver screenshot is the current browser window. It is not automatically a full-page image. If you need one element, use the element screenshot API; if you need a full document, use a browser-specific full-page capability supported by your chosen driver and version. A clipped image can therefore be correct for a viewport capture but wrong for your requirement. Record whether the expected result is viewport, element, or full page before changing code.
Control viewport and rendering conditions
Set the window size explicitly when layout matters:
driver.set_window_size(1440, 1000)
# Then wait for the responsive layout and application data.
Also account for cookie dialogs, overlays, animations, lazy content, and pages that require authentication. Inspect the live DOM and screenshot a known element to distinguish a rendering problem from a scope problem.
Why PhantomJS screenshots fail more often now
The PhantomJS project homepage states that development is suspended. Selenium’s Python change notes identify PhantomJS as deprecated and recommend headless Chrome or Firefox instead: Selenium Python change notes. The current Selenium Python client documentation lists Chrome and Firefox among supported browsers.
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Fix the driver behind crashes, sound loss and screen glitches3Repair Windows errors before they cause bigger problemsRank #3
- Clear visuals. Fluid motion: A 144Hz refresh rate and 1ms MPRT deliver smooth, tear‑free motion across work, gaming, and streaming for clearer, more fluid viewing.
- Eye comfort: TÜV Rheinland 3‑star* certification reduces harmful blue light while preserving stunning color quality without compromise. *TÜV Rheinland 3-star eye comfort certification.
- Wide viewing angle: Get consistent views across a wide 178° /178° viewing angle.
- In-Plane Switching (IPS): See excellent color accuracy and consistency across wide viewing angles with In-plane Switching (IPS) technology.
- Ultra-thin bezels: Maximize your viewing experience with thin bezels.
Old PhantomJS/GhostDriver combinations can fail through stale browser assumptions, unsupported modern JavaScript, missing web APIs, or driver/session incompatibilities. There is no single error that identifies every case. Capture the exact exception, Python and Selenium versions, PhantomJS and GhostDriver versions, operating system or container, URL, output path, return value, and required screenshot scope. Then reproduce the same URL, viewport, readiness condition, and output checks with a maintained browser.
Migrate the smallest possible change
- Keep the URL, test data, viewport, waits, and output validation unchanged.
- Replace the PhantomJS driver construction with headless Chrome or Firefox.
- Run the screenshot and compare page state and dimensions, not only file existence.
- Investigate genuine rendering differences against the browser engine your users support.
The sources establish the migration direction, but they do not establish a universal Chrome-versus-Firefox winner for speed or visual fidelity. Choose based on your application’s browser coverage, deployment environment, driver setup, and required capture scope.
A current Selenium troubleshooting checklist
- Session: Can the browser start, and does
driver.get()reach the intended URL? - Readiness: Is the target element visible and populated, rather than merely past the load event?
- Scope: Do you need the window, one element, or the full page?
- Viewport: Is the window size explicit and appropriate for the responsive layout?
- Output: Is the path absolute, writable, PNG-suffixed, and non-empty?
- Evidence: Did you record versions, URL, exception, return value, and environment?
Common symptoms and targeted fixes
| Symptom | Likely boundary | Action |
|---|---|---|
False from save_screenshot |
File I/O | Use an absolute existing or created directory, check permissions and disk space, and log the resolved path. |
| No file, no exception | Path or cleanup mismatch | Check the process working directory, mounts, cleanup steps, and write the bytes from get_screenshot_as_png() directly. |
| Zero-byte file | Incomplete write or external cleanup | Check the Boolean result, filesystem health, and whether another process touches the artifact directory. |
| Blank page | Browser state or unsupported page behavior | Log URL/title, wait for a page-specific condition, inspect the DOM, and retry with headless Chrome or Firefox instead of PhantomJS. |
| Only the top portion appears | Viewport capture used for a full-page requirement | Use the appropriate element or browser-specific full-page method. |
| Old PhantomJS script breaks on a modern site | Deprecated, suspended browser stack | Migrate the same scenario to a maintained Selenium-supported browser. |
Or skip the browser setup
For a direct website screenshot, ScreenshotNeo provides a GET-based screenshot API and MCP server. It removes cookie and consent banners, newsletter popups, and chat widgets before capture; bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, with the result identified by X-Page-Verdict and X-Billed headers. AI agents can use its MCP tools—take_screenshot, get_page_info, and capture_pdf—from Claude, Cursor, or another MCP client.
See the ScreenshotNeo documentation for all parameters. This one-call example captures Stripe as WebP:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Python:
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)
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 supports full-page and selector captures, dark mode, device presets or custom viewports, retina scale, PDF options, custom CSS and JavaScript, click and wait actions, ad/tracker/request blocking, headers, cookies, user agents, authorization, timezone and geolocation, transparent backgrounds, resizing, chosen cache TTLs, signed links, asynchronous webhooks, bulk capture for up to 100 URLs per call, a usage API, and an OpenAPI specification. Existing parameter names used by other screenshot APIs also work, which can simplify migration.
Rank #4
- CURVED FOR ENHANCED ENGAGEMENT: An immersive viewing experience with a curved monitor that wraps more closely around your field of vision; It creates a wider view, enhancing depth perception and minimizing peripheral distraction
- SMOOTH PERFORMANCE FOR SEAMLESS CONTENT: Stay in the action when playing games, watching videos, or working on creative projects; The 100Hz refresh rate reduces lag and motion blur so you don't miss a thing in fast-paced moments¹
- MORE GAMING POWER: Gain the edge with optimizable game settings; Color and image contrast can be adjusted to see scenes more vividly and spot enemies hiding in the dark; Game Mode adjusts any game to fill the screen so you can view every detail²
- KEEP IT EASY ON THE EYES: Care for your eyes and stay comfortable, even during long sessions; Advanced eye comfort technology certified by TÜV reduces eye strain by minimizing blue light and reducing irritating screen flicker²
- INCREASED VERSATILITY: Connect to more; Plug devices straight into your monitor for increased flexibility, making your computing environment even more convenient
The Free plan includes 1,000 screenshots per month with no card. Paid plans start at $5 for 3,000 shots; every feature is available on every plan. Create a free ScreenshotNeo account to try it.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.FAQ
Does get_screenshot_as_file behave differently from save_screenshot?
Both are documented file-saving interfaces for a PNG screenshot. Use whichever fits your code, but apply the same absolute-path, return-value, and non-empty-file checks.
Can a successful screenshot still be unusable?
Yes. A successful write does not guarantee the desired page state, viewport, element, or full-page scope. Validate those separately.
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Should I keep repairing PhantomJS?
For a maintained pipeline, migration is the safer direction because PhantomJS development is suspended and Selenium deprecated it. Preserve the test conditions while switching to headless Chrome or Firefox.
Best Value
- 【INTEGRATED SPEAKERS】Whether you're at work or in the midst of an intense gaming session, our built-in speakers provide rich and seamless audio, all while keeping your desk clutter-free.
- 【EASY ON THE EYES】 Protect your eyes and enhance your comfort with Blue-Light Shift technology. This feature reduces harmful blue light emissions from your screen, helping to alleviate eye strain during long hours of use and promoting healthier viewing habits.
- 【WIDEN YOUR PERSPECTIVE】Our sleek minimal bezel design ensures undivided attention. The nearly bezel-free display seamlessly connects in a dual monitor arrangement, delivering an unobstructed view that lets you focus on more at once, completely distraction-free.
Frequently Asked Questions
Does get_screenshot_as_file behave differently from save_screenshot?
Both are documented file-saving interfaces for a PNG screenshot. Apply the same absolute-path, return-value, and non-empty-file checks.
Can a successful screenshot still be unusable?
Yes. A successful write does not guarantee the desired page state, viewport, element, or full-page scope.
Should I keep repairing PhantomJS?
For a maintained pipeline, migration is the safer direction because PhantomJS development is suspended and Selenium deprecated it.
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.

