ScreenshotNeo

BlogHow-to

How to Capture a Screenshot of a Web Page with Basic Authentication in Selenium

Authenticate to an HTTP Basic Auth page, wait for protected content, and save a Selenium screenshot. Includes browser caveats and runnable Python code.

By the ScreenshotNeo team4 October 20267 min read

To capture a page protected by HTTP Basic Authentication with Selenium, authenticate the browser first, wait until a known element on the protected page is visible, then call driver.save_screenshot("screenshot.png"). That Python method saves the current browser window as a PNG and returns whether saving succeeded. The screenshot call itself does not authenticate you.

This guide covers HTTP Basic Authentication, where the browser receives an authentication challenge. It is different from a normal HTML login form, which requires filling and submitting page fields.

1. Install Selenium and choose a browser

For the Python example below, install Selenium:

python -m pip install selenium

Use a current Selenium installation and a browser available in your environment. Selenium’s driver setup depends on the browser and execution environment; follow the official WebDriver documentation if the driver is not already available.

The URL passed to driver.get() must include a scheme such as https:// or http://. Use HTTPS wherever the protected site supports it.

2. Authenticate, wait for the protected page, and save a screenshot

One possible approach is to put the username and password in the initial navigation URL. This is browser and provider dependent, so check it in your own environment. Replace the example credentials, page URL, and readiness selector with values for a test account and your application.

from urllib.parse import quote

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait

username = "YOUR_TEST_USERNAME"
password = "YOUR_TEST_PASSWORD"
protected_url = "https://example.test/protected"

# Encode reserved characters in credentials before putting them in a URL.
user = quote(username, safe="")
secret = quote(password, safe="")
prefix, rest = protected_url.split("://", 1)
authenticated_url = f"{prefix}://{user}:{secret}@{rest}"

driver = webdriver.Chrome()
try:
    driver.get(authenticated_url)

    # Choose an element that appears only when the expected protected page is ready.
    WebDriverWait(driver, 15).until(
        EC.visibility_of_element_located((By.CSS_SELECTOR, "main"))
    )

    saved = driver.save_screenshot("screenshot.png")
    if not saved:
        raise RuntimeError("Selenium could not save screenshot.png")
finally:
    driver.quit()

The main selector is only an example. Prefer a stable element or state that proves the authenticated content loaded, such as a protected page heading. A generic page-load event may happen before client-side content is ready.

URL-embedded credentials are a conditional workaround, not a universal Selenium feature. Some browser versions and platforms do not support the pattern, and credentials containing reserved characters need correct URL encoding. Avoid printing or logging the resulting URL: it contains the secret. Do not commit real credentials to source control.

3. Pick an authentication route that fits your environment

Situation Route to consider Things to check
Local run, initial page navigation Try URL-embedded credentials only if your browser supports them. Browser/version compatibility, encoded reserved characters, and whether the page redirects after authentication.
Hosted Selenium provider Check the provider’s documented Basic Auth mechanism. Provider APIs may be proprietary and may differ from local browser behavior.
Later navigation in BrowserStack Automate BrowserStack documents a sendBasicAuth JavaScript executor for its service. This is BrowserStack-specific, not a standard Selenium WebDriver command. Follow the provider’s current instructions and platform limitations.
HTML username/password form Use Selenium to locate the form fields, enter credentials, and submit the form. This is form-based login, not HTTP Basic Authentication; wait for a post-login page state.

BrowserStack documents URL credentials for initial navigation, including encoding concerns and platform limitations, as well as its provider-specific executor for later navigation. Verify the path against the browser and service you actually run: BrowserStack Basic HTTP Authentication documentation.

4. Viewport screenshot versus full-document screenshot

driver.save_screenshot("screenshot.png") captures the current browsing context as a PNG; it is not a promise of a full-page image. Selenium’s WebDriver documentation describes the screenshot endpoint as returning Base64-encoded image data, while the Python convenience method writes the image to a file. See Selenium’s screenshot documentation and the Python WebDriver API.

If you specifically need a full-document screenshot, Selenium’s Python Firefox driver documents get_full_page_screenshot_as_file() and save_full_page_screenshot(). Those methods are Firefox-driver-specific; do not assume the generic screenshot method or every browser driver captures the full document. Consult the Firefox WebDriver API for supported methods.

# Firefox-specific full-document capture
from selenium import webdriver

 driver = webdriver.Firefox()
try:
    driver.get("https://example.test/protected")
    # Authenticate using a method supported by this browser/environment,
    # then wait for the expected protected page state.
    driver.save_full_page_screenshot("full-page.png")
finally:
    driver.quit()

Remove the leading space before driver = if copying this snippet into a script; it should align with the surrounding code. The authentication step is intentionally environment-specific.

5. Troubleshooting

Symptom Likely cause Fix
The browser still shows an authentication prompt or an access-denied page. The browser does not accept credentials in the URL, the credentials are wrong, or the server uses a different authentication flow. Confirm the credentials with a test account. Check browser support and the remote provider’s documented mechanism; use a provider-specific route where required.
Authentication works locally but fails on a hosted browser. The hosted browser has different browser/version/platform behavior. Use the service’s own Basic Auth documentation. Do not assume provider-specific commands work in local Selenium.
The URL breaks when the password contains @, :, or other reserved characters. Reserved characters were inserted without URL encoding. Percent-encode username and password components separately before building the URL. Avoid logging the resulting credential-bearing URL.
The screenshot is blank, incomplete, or shows a loading state. The screenshot ran before the authenticated page or its client-rendered content was ready. Wait for a meaningful protected element or application state. Increase the timeout only if the page legitimately needs more time.
The screenshot file is missing or the save call reports failure. The working directory is unexpected, the target directory is unavailable, or the save operation failed. Use an explicit writable path, check the returned boolean, and raise or log a safe error without including credentials.
The image omits content below the fold. The generic call captured the current window rather than the full document. Use a supported full-document method for the selected browser driver, such as the documented Firefox Python methods, or capture the page in sections.
The script hangs or never reaches the expected element. Authentication did not complete, the selector is wrong, or the page never reached the assumed state. Inspect the page state in a secure local run, validate the selector, and handle timeout exceptions with a diagnostic that does not expose secrets.

6. Reliability, performance, and credential handling

  • Wait for page meaning, not just navigation. A reliable expected element reduces screenshots taken during redirects or rendering.
  • Keep secrets out of artifacts. Use test credentials, environment-based secret injection, and access controls for logs and screenshots. A URL containing credentials can be retained by browser or provider logs.
  • Always close the browser. Put driver.quit() in a finally block so failures do not leave browser processes running.
  • Keep capture scope realistic. Viewport shots are generally smaller and simpler than very tall full-document captures. Large pages can take longer and produce larger files.
  • Check the output. Verify the save result and, in automated workflows, confirm the file exists and is non-empty before passing it downstream.

The cited Selenium and BrowserStack documentation does not establish a universal authentication workaround or benchmark for capture speed. Browser support, page rendering, network latency, and remote execution all affect the result, so validate the chosen route in the target environment.

Or skip the browser setup

If you only need a screenshot of a publicly accessible page, ScreenshotNeo returns a screenshot or PDF from one API request. It cannot use your Selenium browser session or authenticate to an HTTP Basic Authentication page with the credentials in this guide; use Selenium for that protected page. ScreenshotNeo can simplify captures for public pages and pages accessible to its API.

See the ScreenshotNeo API documentation. Example request:

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}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
const bytes = new Uint8Array(await res.arrayBuffer());
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', bytes));

ScreenshotNeo removes cookie banners, popups, and chat widgets before the shot; bot checks, blank pages, and failed loads are never billed. Its MCP server lets AI agents take screenshots. The free plan includes 1,000 screenshots a month with no card, and paid plans start at $5 for 3,000. Sign up free and capture 1,000 screenshots a month with no card.

FAQ

Does Selenium’s screenshot command handle Basic Authentication?

No. The browser must authenticate successfully first. Then the screenshot method captures the current page.

Can I use the same authentication technique in every browser?

No. URL credentials and provider mechanisms vary by browser, version, platform, and execution service. Verify the method for your actual setup.

Does save_screenshot() capture the whole page?

It captures the current browsing context. Selenium’s documented full-document Python methods are specific to Firefox’s driver.

Is HTTP Basic Authentication the same as a login form?

No. Basic Authentication is an HTTP authentication challenge; a login form is HTML that your automation must interact with.