What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
Short answer: stop trying to repair a new PhantomJS setup. PhantomJS development is suspended, and Selenium deprecated its integration in favor of headless Chrome or Firefox. Create an isolated Python environment, upgrade Selenium, let Selenium Manager find the browser driver, then diagnose discovery, session-startup, and page-synchronization errors as separate problems.
Why PhantomJS errors keep appearing
PhantomJS is not a current Selenium target. Selenium’s 3.8.1 change log states: “PhantomJS is now deprecated, please use either Chrome or Firefox in headless mode.” The PhantomJS project page says, “Important: PhantomJS development is suspended until further notice.” Its maintainers identified the lack of active contribution as the reason for suspension; version 2.1.1 remained the last known stable release.
That means errors such as WebDriverException, missing executables, unsupported capabilities, and session failures are usually symptoms of an obsolete toolchain rather than a missing PhantomJS option. Replace webdriver.PhantomJS(...) and PhantomJS-specific desired capabilities with a supported browser.
Start with a clean, current Python setup
1. Record the environment
Before changing code, write down:
- Python version and operating system
- Selenium package version (
python -m pip show selenium) - Installed Chrome or Firefox version
- Whether the test runs locally, in CI, or against a remote Selenium server
- The complete exception and driver log
Version mismatches are common, but the compatible combination depends on the browser and release. Capturing these details prevents a “fix” that only works on one machine.
#1 Best Overall
2. Use a virtual environment and upgrade Selenium
python -m venv .venv
# macOS/Linux
source .venv/bin/activate
# Windows PowerShell: .venvScriptsActivate.ps1
python -m pip install --upgrade pip
python -m pip install --upgrade selenium
python -m pip show selenium
Current Selenium Python releases can invoke Selenium Manager when a WebDriver is created. Selenium Manager resolves or downloads the required browser driver in supported installations, so many old instructions telling you to download a driver manually are now legacy guidance. You still need the target browser installed unless your deployment image provides it another way.
Replace PhantomJS with headless Chrome or Firefox
Headless Chrome
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
options = Options()
options.add_argument("--headless=new")
options.add_argument("--window-size=1440,1000")
driver = webdriver.Chrome(options=options)
try:
driver.get("https://example.com")
print(driver.title)
finally:
driver.quit()
Headless Firefox
from selenium import webdriver
from selenium.webdriver.firefox.options import Options
options = Options()
options.add_argument("-headless")
driver = webdriver.Firefox(options=options)
try:
driver.get("https://example.com")
print(driver.title)
finally:
driver.quit()
Both examples use Selenium’s current Options APIs and avoid a hard-coded driver path. Choose the browser whose JavaScript behavior, rendering, CI image, operating-system support, startup characteristics, and debugging tools best match the site you automate. Selenium’s deprecation notice establishes Chrome and Firefox as the migration targets; it does not establish a universal speed or reliability winner.
When an explicit driver path is unavoidable
Some locked-down CI images, air-gapped hosts, or enterprise policies require a preinstalled driver. Use Selenium’s Service object rather than the removed PhantomJS constructor:
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 matchfrom selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
options = Options()
options.add_argument("--headless=new")
service = Service("/opt/webdriver/chromedriver")
driver = webdriver.Chrome(service=service, options=options)
Check that the file exists, is executable, and belongs to the browser version installed in the same image. If Selenium Manager is available, remove stale paths first; a path copied from an old tutorial can force Selenium to use an incompatible binary.
Rank #2
Diagnose the exception by class
NoSuchDriverException: Selenium cannot locate the driver
This is a discovery or installation failure, not a page-locator problem. Confirm that Chrome or Firefox is installed, upgrade Selenium, and inspect Selenium Manager’s diagnostic output. Then check:
- Whether the driver is on
PATHor supplied through a correctServicepath - Executable permissions on Linux and macOS
- That the CI container actually contains the browser and driver
- Corporate proxy, download, or certificate restrictions that prevent Selenium Manager from obtaining a driver
Run the same script outside CI. If it works locally, compare the image, environment variables, permissions, and network policy rather than changing locators.
SessionNotCreatedException: the browser session cannot start
A session-creation failure occurs after Selenium has attempted to launch the browser. Compare browser and driver versions, remove obsolete hard-coded binaries, and read the driver log. In containers, verify the headless flags and sandbox policy required by that image; a flag that fixes one container can be inappropriate or insecure in another. Also check that another process is not occupying the debugging or profile resources your browser needs.
NoSuchElementException and timeout errors
A successful get() call only means navigation was requested. Dynamic content may still be loading, an element may be inside an iframe, or a consent overlay may cover the page. Selenium identifies poor synchronization as its most common reported error.
Rank #3
Use an explicit wait for the state you actually need:
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, 20)
button = wait.until(
EC.element_to_be_clickable((By.CSS_SELECTOR, "button[data-testid='buy']))
)
button.click()
Prefer stable IDs, accessible labels, or purpose-built data attributes over brittle absolute XPath. If a wait expires, inspect the current URL and page source, verify the locator in browser developer tools, and confirm that the expected element is not in a different frame or window.
Frames and windows
Switch into the iframe before locating its contents:
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Scan for outdated or missing drivers - takes under a minuteDriver Scan →frame = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "iframe.payment")))
driver.switch_to.frame(frame)
wait.until(EC.visibility_of_element_located((By.NAME, "cardnumber")))
driver.switch_to.default_content()
For a new tab, wait for the window count, then switch explicitly:
Rank #4
old_handles = driver.window_handles
# trigger the link or action here
wait.until(lambda d: len(d.window_handles) > len(old_handles))
new_handle = next(h for h in driver.window_handles if h not in old_handles)
driver.switch_to.window(new_handle)
Stale, intercepted, and non-interactable elements
StaleElementReferenceException means the page replaced the node after you located it. Locate it again after the update. ElementClickInterceptedException commonly indicates an overlay, animation, or another element covering the target; wait for the overlay to disappear and for the target to be clickable. ElementNotInteractableException means the node exists but is hidden, disabled, or otherwise not ready. Scrolling, waiting for visibility, or using the correct control can fix it; JavaScript clicking should be a last resort because it can bypass the user behavior your test is meant to verify.
A repeatable troubleshooting workflow
- Reduce the case. Reproduce with one URL and one action, keeping the full stack trace.
- Verify browser startup. Run a script that only opens a page and prints its title.
- Classify the failure. Separate driver discovery, session creation, navigation, synchronization, frame/window, and interaction errors.
- Turn on useful logs. Preserve Selenium Manager and browser-driver logs in CI artifacts; record Python, Selenium, browser, driver, and OS versions.
- Check the page state. Save the current URL and a screenshot when a wait fails. This distinguishes a redirect, login page, bot check, blank response, or changed markup.
- Try another browser. Repeating the operation in Chrome and Firefox helps determine whether the defect is in your Selenium code or an underlying browser driver.
- Make synchronization explicit. Replace fixed sleeps with waits for presence, visibility, clickability, a URL change, or a custom condition.
- Rebuild the CI image. Ensure the browser, fonts, shared libraries, permissions, and sandbox configuration are present and consistent with local development.
Reliability and performance choices
Headless mode removes the visible window but does not remove browser rendering, JavaScript, network, or security behavior. Keep browser profiles isolated between parallel jobs, call quit() in a finally block, and avoid sharing a driver instance across unrelated tests. Use a realistic page-load and explicit-wait policy instead of one very long global timeout: long waits hide regressions, while short waits create false failures on a busy CI runner.
Do not assume Chrome or Firefox is universally faster. Measure startup time, memory use, navigation behavior, and test stability in your own operating system and deployment image. A cross-browser pass is also a useful compatibility check for the application under test.
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Scan for outdated or missing drivers - takes under a minute3Repair Windows errors before they cause bigger problemsOr skip the browser setup
If your goal is a clean image or PDF rather than interactive browser testing, ScreenshotNeo provides a website screenshot API and MCP server. It accepts a URL in one request and can return PNG, JPEG, WebP, or PDF. Before capture, it accepts cookie or consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each step can be disabled. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the result with X-Page-Verdict and X-Billed headers.
See the full parameter list and OpenAPI details in the ScreenshotNeo documentation. A minimal cURL request is:
Best Value
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 also offers an MCP server for Claude, Cursor, and other MCP clients, with take_screenshot, get_page_info, and capture_pdf tools. Its options include full-page lazy-image capture, CSS-element capture, dark mode, device presets, custom viewport and retina scale, PDF paper settings, custom CSS and JavaScript, click and wait actions, request blocking, headers, cookies, user agents, authorization, timezone, geolocation, transparent backgrounds, resizing, chosen cache TTLs, signed image links, asynchronous webhooks, bulk capture of up to 100 URLs per call, and a usage API. Every feature is on every plan: 1,000 shots per month free with no card; paid plans start at $5 for 3,000 shots.
Create a free ScreenshotNeo account to use the 1,000 monthly shots without entering a card.
Frequently Asked Questions
Can I keep PhantomJS installed for an old test suite?
You can preserve an isolated legacy environment for historical runs, but it will not receive ongoing development. New tests should target headless Chrome or Firefox.
Should I use implicit and explicit waits together?
Use one deliberate synchronization strategy. Mixing a long implicit wait with explicit waits can make timeout behavior difficult to predict; explicit waits with clear conditions are easier to diagnose.
Does headless mode test exactly what a headed browser displays?
It exercises the same browser engine, but viewport size, GPU behavior, fonts, permissions, and environment settings can differ. Set the viewport deliberately and validate important flows in the deployment environment.
When should I use a remote Selenium server instead of a local driver?
Use a remote server when browsers are centrally managed, distributed across machines, or required for a browser matrix. The same discovery and synchronization distinctions still apply; remote-server logs and network reachability become additional checks.
Recommended Free Tools
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.

