ScreenshotNeo

BlogHow-to

How to take a Selenium screenshot of a page after dismissing a cookie banner

Wait for the site’s consent control, click it, verify the banner is gone, and then capture the page with Selenium. Includes iframe, cookie, and troubleshooting guidance.

By the ScreenshotNeo team4 October 20262 min read

To take a Selenium screenshot after dismissing a cookie banner, locate the site’s actual consent control, wait until it is clickable, click the intended option, then wait until the banner is invisible or verify another site-specific success condition. Capture only after that condition is met. There is no universal cookie-banner selector: markup and consent choices vary by site.

The Python example below uses illustrative selectors. Inspect the target page and replace them with selectors that match its consent UI.

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

URL = "https://example.com"
# Illustrative placeholders; inspect the target site and replace these.
consent_button = (By.CSS_SELECTOR, "button[data-testid='cookie-accept']")
banner = (By.CSS_SELECTOR, "[role='dialog']")

with webdriver.Chrome() as driver:
    driver.get(URL)
    wait = WebDriverWait(driver, 10)

    wait.until(EC.element_to_be_clickable(consent_button)).click()
    wait.until(EC.invisibility_of_element_located(banner))

    if not driver.save_screenshot("page.png"):
        raise OSError("Could not save screenshot")

Install Selenium with python -m pip install selenium. Selenium Manager can manage browser drivers for supported setups; the browser itself must still be installed. See the Selenium documentation and ScreenshotNeo API documentation for the browser workflow and API alternative.

Use the page’s own interface and a consent choice appropriate to your test or use case. “Accept” is not a universal choice. A site may offer accept, reject, manage preferences, or another action. Select the intended control by a stable attribute, accessible role/name, or other locator you verified on that site.

For example, after inspecting the page, a locator might use a button label or a data attribute. The example selector button[data-testid='cookie-accept'] is only a placeholder; it is not known to exist on example.com or any other site. Avoid selectors based on incidental styling classes when a more stable attribute is available.

If the banner is inside an iframe, Selenium must switch into that frame before finding its controls. Locate the frame in the top-level document, wait for it, switch, then locate and click the button inside it:

frame = wait.until(
    EC.presence_of_element_located((By.CSS_SELECTOR, "iframe#consent-frame"))
)
driver.switch_to.frame(frame)

button = wait.until(
    EC.element_to_be_clickable((By.CSS_SELECTOR, "button[data-testid='cookie-accept']"))
)
button.click()

# Switch back if subsequent page checks use top-level content.
driver.switch_to.default_content()

Both selectors in this iframe example are placeholders. Some sites remove the iframe after consent; others keep it but hide its contents. Choose a post-click condition that matches the observed behavior.

2. Wait for dismissal instead of guessing a delay

A fixed sleep can be too short on a slow page and waste time on a fast one. An explicit wait expresses the condition that matters. Selenium’s expected conditions include clickability and invisibility. If the site removes the banner element, invisibility also succeeds when the element is no longer attached to the page.

The basic sequence is:

  1. Navigate to the page.
  2. Wait for the intended consent control to be clickable.
  3. Click it once.
  4. Wait for the banner to disappear, become stale, or for another verified page state.
  5. Save the screenshot.

If the banner disappears but a backdrop remains, wait for both elements to be invisible. If the site updates a preference panel instead of removing the banner, verify the resulting state rather than waiting for a selector that will never disappear.

3. Capture the right screenshot output

driver.save_screenshot("page.png") saves a PNG of the current window and returns a boolean: it returns False on an I/O error and otherwise True. Check the result if the saved file is part of a build or test artifact.

For image processing in memory, use PNG bytes; for embedding where a base64 string is needed, use the base64 method:

png_bytes = driver.get_screenshot_as_png()
with open("page.png", "wb") as output:
    output.write(png_bytes)

png_base64 = driver.get_screenshot_as_base64()

These ordinary methods capture the current window or viewport. Do not assume they capture the full document. Selenium’s Firefox driver documents separate full-document screenshot methods; support and behavior depend on the browser driver. If you need a full-page image, confirm the method for your chosen driver and verify the output dimensions.

Clicking the visible control exercises the site’s user-facing flow. Direct cookie setup can be useful in a controlled test when the relevant cookie name, value, domain, and expected consent state are known. It is not a universal substitute: sites may use other persistence mechanisms, additional state, or UI behavior that a cookie alone does not reproduce.

Selenium requires the browser to be on a domain for which a cookie is valid before adding it. A typical controlled setup navigates to the domain, adds a known cookie, then reloads and checks the resulting page. Cookie names and values below are placeholders, not a real consent recipe:

driver.get("https://example.com")
driver.add_cookie({
    "name": "CONSENT_COOKIE_NAME",
    "value": "KNOWN_TEST_VALUE",
    "path": "/",
})
driver.refresh()
# Verify the banner or expected consent state before capturing.

Use the visible UI when the test is meant to cover the consent interaction. Seed cookies only when the test intentionally starts from a known state and the site’s documented or inspected behavior supports it.

5. Common failures and fixes

Symptom Likely cause Fix
Element not found The illustrative selector does not match the site, the banner has not rendered, or the control is inside an iframe. Inspect the live DOM, wait for the correct element, and switch into the relevant frame before locating its controls.
Click intercepted or not clickable An animation, overlay, or another element is covering the button, or it is still disabled. Wait for clickability and inspect the overlay. Wait for the banner’s own transition to finish if needed, then use the intended visible control.
Wait for invisibility times out The selector points at the wrong container, the site keeps the container visible, or the action did not dismiss the banner. Check the post-click DOM and wait for the actual success condition: a hidden banner, a stale element, a closed dialog, or a confirmed page state.
Screenshot still contains the banner The screenshot ran before dismissal completed, or the selector only tracked part of the consent UI. Wait for all visible banner/backdrop elements to disappear and capture after the wait. Confirm the screenshot is taken from the same tab and frame state.
Cookie insertion fails The browser is not currently on a matching domain, or the cookie attributes do not fit that domain. Navigate to the target domain first and use the site’s actual cookie scope. Reconsider whether the test should click the UI instead.
Screenshot save returns false or file is missing The output path is unwritable or the process cannot write to the destination. Use a writable path, create its parent directory, and check the method’s boolean return value.
Screenshot is clipped The method captures the current window rather than the full document. Use a full-document capture method documented for the selected browser driver, or capture the required viewport explicitly.

6. Reliability, runtime, and cost considerations

Explicit waits make the sequence depend on page state rather than an arbitrary pause, but they cannot make an incorrect locator or an ambiguous consent outcome reliable. Keep selectors and success conditions specific to the target site, and fail clearly when the expected state does not appear. For repeatable automation, use a known browser version and a clean or deliberately seeded browser profile; persisted consent in a reused profile can cause the banner not to appear during a test.

Runtime is dominated by navigation, site loading, and the time until the consent control and post-click state are ready. A bounded explicit wait keeps failures finite. Avoid adding a long fixed sleep on top of state-based waits unless the page has a specific delayed behavior you have observed.

Selenium itself is open source, but a browser automation run still consumes compute and requires browser/driver setup. For recurring captures, compare that setup and maintenance with a screenshot API’s per-plan allowance and behavior. ScreenshotNeo bills only clean shots: bot checks/CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers indicate the page verdict and billing status.

7. Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server for developers. One GET request returns a PNG, JPEG, WebP, or PDF. Its capture flow accepts cookie/consent banners like a visitor and removes 60+ known consent platforms, newsletter popups, and chat widgets before the shot; each step can be turned off.

For a quick PNG capture, replace YOUR_API_KEY with your key and change the target URL:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
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)
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}`);
await Bun.write("shot.webp", res);

For Node.js environments without Bun, write the response body using that runtime’s file APIs. See the API docs for authentication, output formats, options, and response headers. The service also offers an MCP server with take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients.

Bot checks, blank pages, and failed loads are never billed. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000. Every feature is on every plan. Sign up for 1,000 free screenshots a month with no card.

8. FAQ

No. Inspect each target site and use its actual consent control and resulting state.

Should my automation always accept cookies?

No. Choose the action that matches your test or consent requirements; acceptance is not a universal default.

No. Cookie scope and the site’s persistence behavior are site-specific, and the banner may depend on more than one value.

Does save_screenshot() capture the whole page?

It captures the current window. Full-document capture depends on the browser-specific driver API.