October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsSlow PC?RecommendedPC slow today? Run a repair scan before it gets worseResolve common Windows issues and optimize system performance.Scan NowOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
browser automation

How to Block Cookie Modals When Scraping with Playwright, Selenium, or an API

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use a real browser context, identify what is blocking the page, and make an explicit choice. A native JavaScript dialog needs dialog.accept() or dialog.dismiss(). A DOM banner should be rejected or closed with a site-specific locator, including a frame locator when the consent manager runs in an iframe. If the site stores consent in cookies or local storage, create an isolated context and restore that state on later runs. Do not assume that disabling cookies, deleting an overlay, or clicking an arbitrary button represents valid consent.

The reliable workflow is: classify the obstruction, choose “Reject” (or another documented policy), persist the resulting state, and verify that the page remains usable. The examples below show Playwright first, then Selenium, followed by an API option when you only need a clean image or PDF.

Classify the obstruction before changing cookies

“Cookie modal” can mean three different browser behaviors. Inspect the page and browser events before writing a selector or changing privacy settings.

Native JavaScript dialogs

alert, confirm, prompt, and beforeunload are browser dialogs, not HTML. Playwright auto-dismisses dialogs by default. If you register a listener, always settle it; an unhandled dialog can pause the action that triggered it.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
page.on('dialog', async dialog => {
  console.log(`${dialog.type()}: ${dialog.message()}`);
  await dialog.dismiss();
});

Accept only when your policy requires the dialog’s affirmative action. For a confirmation that must be accepted, replace dismiss() with accept(). Never leave a listener that logs but does not call either method.

DOM banners and modal overlays

Most consent notices are ordinary elements. Locate the visible dialog by an accessible role and button name, stable data attribute, or a known iframe. Prefer the site’s “Reject all”, “Necessary only”, or equivalent control. A close icon that merely hides the panel may leave consent unset.

For a predictable banner, wait for the control and click it explicitly. For an intermittent overlay, current Playwright releases provide page.addLocatorHandler(), which runs a self-contained handler before an action or assertion encounters the matching locator. The handler can change focus and mouse state, so subsequent actions should not depend on the previous focus.

Persisted consent state

Consent-management platforms commonly check cookies or local storage before displaying a notice. You can create a fresh context, make the documented choice once, save storageState, and restore it for repeatable runs. Cookie domain, path, expiry, and the meaning of each value are site-specific; never copy a cookie name or value between domains without verifying it.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Playwright: reject the banner and reuse the decision

Install Playwright and its browser, then pass a target URL on the command line:

npm install playwright
npx playwright install chromium

This complete Node.js example handles native dialogs, an accessible DOM dialog, and a saved state. The regular expression is intentionally narrow enough to avoid clicking unrelated buttons; adapt the words to the target site.

import { chromium } from 'playwright';

const targetUrl = process.argv[2] ?? 'https://example.com';
const browser = await chromium.launch({ headless: true });
const context = await browser.newContext();

// Put site-specific pre-load logic here when the CMP requires it.
await context.addInitScript({ content: '/* site-specific hook */' });

const page = await context.newPage();
page.on('dialog', async dialog => {
  console.log(`Dismissing ${dialog.type()} dialog: ${dialog.message()}`);
  await dialog.dismiss();
});

await page.addLocatorHandler(page.getByRole('dialog'), async dialog => {
  const reject = dialog.getByRole('button', {
    name: /reject|necessary only|deny|decline/i
  });
  if (await reject.count()) {
    await reject.first().click();
    return;
  }
  const close = dialog.getByRole('button', { name: /close/i });
  if (await close.count()) await close.first().click();
});

await page.goto(targetUrl, { waitUntil: 'domcontentloaded' });

// A site-specific assertion is better than assuming the modal is gone.
const consentDialog = page.getByRole('dialog');
if (await consentDialog.count()) {
  await consentDialog.first().waitFor({ state: 'hidden', timeout: 5000 }).catch(() => {});
}
await page.screenshot({ path: 'page.png', fullPage: true });
await context.storageState({ path: 'consent-state.json' });
await browser.close();

Run the first visit once, inspect the saved state, and then restore it on subsequent jobs:

const context = await browser.newContext({ storageState: 'consent-state.json' });

Keep the state file private: it can contain authentication and preference data as well as consent. Regenerate it when the site changes its consent manager or when the stored expiry has passed.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

When the banner is inside an iframe

A top-level getByRole('dialog') cannot see elements in another browsing context. Identify the frame by a stable name or URL fragment and use frameLocator:

const cmp = page.frameLocator('iframe[title*="consent" i]');
await cmp.getByRole('button', { name: /reject|necessary only/i }).click();

If the iframe is injected late, wait for the iframe element first. Avoid broad selectors such as “the first button on the page”; they are fragile and can trigger an unrelated action.

Using an initialization hook

addInitScript runs before the page’s scripts, which is useful for a site-specific hook that reads or sets a preference before the consent manager initializes. The hook must match that site’s implementation. A generic script that removes every element containing the word “cookie” can hide legitimate content and does not prove that tracking was disabled.

Selenium alternative

Selenium WebDriver can drive Chrome in the same way, but the browser and ChromeDriver major versions must match. Selenium does not define a universal cookie-banner selector, so the locator remains site-specific.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
from selenium import webdriver
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait

options = webdriver.ChromeOptions()
options.add_argument('--headless=new')
driver = webdriver.Chrome(options=options)
try:
    driver.get('https://example.com')
    wait = WebDriverWait(driver, 10)
    try:
        reject = wait.until(EC.element_to_be_clickable((
            By.XPATH,
            "//button[contains(translate(normalize-space(.), 'REJECTDENY', 'rejectdeny'), 'reject') or contains(translate(normalize-space(.), 'NECESSARYONLY', 'necessaryonly'), 'necessary')]"
        )))
        reject.click()
    except TimeoutException:
        pass  # No matching banner appeared; record this outcome.
    # Continue only after a page-specific readiness check.
    print(driver.title)
finally:
    driver.quit()

For a repeatable Selenium run, make the choice once, call driver.get_cookies(), and restore only the cookies whose domain, path, and expiry you have verified. Add cookies after opening the matching origin and before loading the protected page; otherwise WebDriver will reject them or the site will ignore them.

Why browser-wide cookie blocking is not a universal fix

Firefox and Safari apply stronger third-party-cookie protections by default than Chrome. Chrome generally does not block third-party cookies outside Incognito or an explicit setting. Blocking cookies can also break embedded media, payment widgets, login flows, and social components. Treat the browser setting as a diagnostic or privacy control, not as a modal-removal technique.

A consent manager may display a notice because it has no valid preference, record the response, and pass the status to analytics and advertising systems. Deleting the banner from the DOM neither records a rejection nor guarantees that tags stopped running. Make the policy decision visible in your scraper configuration and logs.

Choose the method that matches your target

Method Reliability across sites Records an explicit choice Repeatability Main risk
Click “Reject” in the page DOM Good when selectors are maintained Usually, if the site control is genuine Good after saving state Selector changes or delayed rendering
Click inside a consent iframe Good after frame discovery Usually Good Frame URL, title, or nesting changes
Restore verified cookies/local storage Very good for one stable site Only if state came from a real documented choice Very good until expiry or CMP changes Wrong domain, path, or stale semantics
Remove the overlay with JavaScript Low No Low Tracking or layout can continue invisibly
Block cookies globally Inconsistent No Inconsistent Broken functionality and third-party components

For intermittent overlays, a locator handler is convenient. For a high-volume crawl of one domain, a verified storage state is faster and less brittle. For multiple unrelated domains, keep separate contexts and state files so one site’s consent data cannot leak into another.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Make scraping repeatable and defensible

Record the decision

Log the URL, timestamp, action taken (“Reject all”, “Necessary only”, or no banner), browser version, and whether the state was restored or created. Keep the consent-state file alongside a versioned scraper configuration, not in source control if it contains other cookies.

Wait for the right event

domcontentloaded confirms that the initial document is parsed, not that a delayed CMP has finished. Use a short, site-specific wait for the dialog or its absence, then wait for the content you actually need. A blanket networkidle wait can be slow on pages with analytics or streaming requests.

Handle retries without duplicating consent

Reuse the same context for related pages on one domain. If navigation fails, retry the page load rather than clicking the consent control repeatedly. On a new context, expect the banner again unless a valid state is supplied.

Respect access and privacy rules

Check the site’s terms, robots directives, and applicable privacy law. Do not treat a hidden banner as proof of consent, and do not collect personal data merely because the browser can display it. “Reject” should be your documented default where it is available and consistent with your legal basis.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Common failures and fixes

Symptom Likely cause Fix
Locator times out Banner is delayed, renamed, or inside a frame Wait for the container, inspect frames, and use a stable role, text, or data attribute.
Click is intercepted Another overlay, animation, or focus trap is active Use a self-contained locator handler, wait for visibility, and avoid force-clicking until the cause is understood.
Banner returns every run Consent was not stored, storage is partitioned, or state expired Inspect cookies and local storage after the click; verify domain/path and save the context state.
Saved state has no effect State belongs to another host or the CMP uses a server-side account preference Create the state on the exact origin and confirm the preference through the site’s own UI.
Native dialog freezes the test A listener was added without accepting or dismissing Call dialog.accept() or dialog.dismiss() on every event.
Page breaks after cookie blocking Required third-party cookies or embedded components were blocked Restore normal cookie behavior and handle the consent UI instead.
Overlay disappears but tags still fire Only the DOM node was removed Use the site’s reject control or a verified state; removing pixels is not a consent signal.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup

If your goal is a clean screenshot or PDF rather than an interactive crawl, ScreenshotNeo makes one HTTP request to capture a URL. Before the capture it accepts the cookie or consent banner like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each cleanup step can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and the response reports the result in X-Page-Verdict and X-Billed headers.

Use the API documentation at https://screenshotneo.com/docs/ for authentication and all options.

cURL

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}`);

You can also use custom CSS or JavaScript, hide selectors, wait for a selector, delay, or network idle, choose a device and viewport, load lazy images in full-page captures, block selected requests, set headers, cookies, user agent, timezone, geolocation, or authorization, and capture an element, image, or PDF. An MCP server exposes take_screenshot, get_page_info, and capture_pdf to Claude, Cursor, and other MCP clients. Those controls are useful when a target uses a banner that is not among the known cleanup rules, but they do not turn an image capture into a consent decision for a data-collection crawler.

Every feature is included on every plan. Current monthly plans are:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Plan Price Included shots
Free $0 1,000 per month; no card
Starter $5 3,000
Growth $15 15,000
Pro $39 60,000
Scale $99 250,000
Business $249 1,000,000

Yearly billing gives two months free. Start with 1,000 free screenshots a month with no card; paid plans start at $5 for 3,000 shots.

Historical context for cookie banners

Older measurements illustrate why behavior varies, but they are not current global estimates. A longitudinal ePrivacy review reported in a 2020 paper found that 49% of sampled websites placed cookies before receiving consent and 28% provided no consent mechanism. In a 2019 UK sampling frame, five CMP vendors—QuantCast, OneTrust, TrustArc, Cookiebot, and Crownpeak—accounted for approximately 58% combined market share in the cited methodology. Treat these figures as historical and study-specific, not as a prediction for the site you are scraping.

FAQ

Can I debug the same flow without headless mode?

Yes. Set Playwright’s headless option to false or remove Selenium’s headless argument, slow the actions, and inspect the banner and frames in a visible browser. Switch back to headless only after the site-specific selectors and waits are stable.

How should I prove which consent action a job took?

Store a structured log containing the target origin, UTC timestamp, selected action, selector or frame used, and whether a prior state was restored. Keep screenshots or HTML only when your data policy permits them, and protect any state file that may contain authentication cookies.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

When should a saved consent state be rebuilt?

Rebuild it after a consent-manager redesign, a domain migration, a browser-profile change, or an expiry observed in the cookie/local-storage record. A state file is an optimization for a verified decision, not a permanent substitute for checking the site’s current controls.

Frequently Asked Questions

Can I debug the same flow without headless mode?

Yes. Set Playwright’s headless option to false or remove Selenium’s headless argument, slow the actions, and inspect the banner and frames in a visible browser. Switch back to headless only after the site-specific selectors and waits are stable.

How should I prove which consent action a job took?

Store a structured log containing the target origin, UTC timestamp, selected action, selector or frame used, and whether a prior state was restored. Keep screenshots or HTML only when your data policy permits them, and protect any state file that may contain authentication cookies.

When should a saved consent state be rebuilt?

Rebuild it after a consent-manager redesign, a domain migration, a browser-profile change, or an expiry observed in the cookie/local-storage record. A state file is an optimization for a verified decision, not a permanent substitute for checking the site’s current controls.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

Leave a Reply

Your email address will not be published. Required fields are marked *

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Read next

Recommended PC Tool
Recommended PC Tool
Outdated Drivers Are Slowing You DownFree scan - exact matches
PC Slower Than It Used to Be?Free scan - under a minute

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.