Cookie Consent Banner Automation for Clean Screenshots
September 30, 2026


Why Cookie Banners Keep Ruining Your Screenshots and Scrapes
You fire off a screenshot request and get back an image with a gray overlay and a cookie consent panel sitting over the hero section — sometimes the entire viewport. This is one of the most common complaints from teams doing cookie consent banner automation for screenshot pipelines, and it's not a garden-variety rendering timing bug.
Three distinct failure modes show up depending on what you're capturing. A standard viewport screenshot gets a GDPR banner blocking the fold content you wanted for a client or a visual regression suite. A full-page screenshot is worse: many consent walls apply overflow: hidden or a scroll-lock class to while open, and if that class isn't cleaned up before capture, you get truncated pages, blurred backgrounds, or extra whitespace. And when scraping HTML or text, the banner's DOM nodes — "We use cookies to improve your experience," "Accept All," "Manage Preferences" — get vacuumed into your structured data alongside the content you actually wanted, corrupting anything downstream that assumes clean article or product text.
None of this is solved by simply waiting longer. It's a detection-and-dismissal problem, not a load-time problem — which is exactly why it needs its own strategy.
Why There's No Single Selector That Works Everywhere
The instinct is to grab the banner's class name from DevTools and add .cookie-banner { display: none } to your capture script. That works for exactly one site, once, until the vendor ships a markup update.
Consent banners are rendered by dozens of different consent management platforms, each with its own DOM conventions. A OneTrust banner typically lives in a container with #onetrust-banner-sdk and nested accept/reject buttons with vendor-specific IDs. A Cookiebot selector usually targets #CybotCookiebotDialog. Didomi, TrustArc, Osano, and countless in-house banners each do it differently again — some rendering directly into the main document, others injecting into shadow DOM (invisible to simple querySelector calls unless you pierce the shadow root), and others loading the entire banner inside an iframe, isolating it from your page context entirely.
Layered on top of vendor-specific markup is the IAB Transparency and Consent Framework. Many CMPs implement the __tcfapi stub function, a standard programmatic interface for reading and setting consent state — but plenty of sites run a proprietary banner unrelated to TCF entirely. Understanding the TCF actors — publishers, CMPs, and the Global Vendor List explains why the same "accept" click behaves so differently across sites: you're not clicking one API, you're clicking whatever bespoke UI a given CMP vendor shipped this quarter. Consent management platform detection — figuring out which system you're dealing with before trying to dismiss anything — is the actual prerequisite most brittle scripts skip.
Four Ways to Dismiss a Banner Programmatically (and Their Trade-offs)
1. Consent cookie injection. Set the cookies a given CMP checks for (e.g., a OptanonConsent or CookieConsent cookie) before navigation, so the site's own script decides consent was already given and never renders the banner. Fast and clean, but you need the exact cookie name, value format, and expiry per vendor — another lookup table to maintain.
2. Rule-based selector click-through. This is the approach behind Consent-O-Matic, an open-source project maintaining 200+ CMP rule sets with detection methods like OPEN_OPTIONS, DO_CONSENT, SAVE_CONSENT, and HIDE_CMP. It works well only because someone continuously updates those rules as vendors change markup — the exact maintenance burden you're trying to avoid.
3. CSS/DOM suppression. Injecting a stylesheet or removing elements matching known banner containers after render. A display:none rule can hide the visible overlay, but doesn't reliably remove every banner: iframe-hosted consent walls, shadow-DOM banners, and the underlying scroll-lock class on often survive a simple CSS override, leaving layout artifacts even though the box itself is invisible.
4. __tcfapi programmatic consent. For TCF-compliant sites, calling __tcfapi for getTCData or to push a consent signal lets you interact with the actual consent layer rather than its UI — more robust where supported, but useless on the large share of sites running non-TCF, custom-built banners.
Each technique alone covers only part of the landscape; production systems typically need to try all four in sequence.
Timing It Right: Detect the Banner Before You Capture
Consent banners rarely exist in the initial DOM — they're usually injected asynchronously by a third-party script seconds after first paint, often with a CSS transition. Fire your capture too early and you might miss the banner (lucky, but unreliable); fire it mid-animation and you screenshot a half-slid-in panel or click a button that hasn't finished becoming interactive — a genuine race condition that looks like a timing issue but is really a sequencing one.
The reliable pattern is poll-then-act: wait for a known banner selector (or a small set of candidates) to appear and stabilize, then dismiss it, then capture — rather than a flat fixed delay. This is a specific case of the broader problem covered in our practical decision tree for headless browser wait strategies, and it compounds directly with full-page capture bugs discussed in fixing what fullPage:true breaks, since a banner still animating when scroll-lock is removed is a common source of the blank-space and clipping artifacts reported there.
Doing This With Browsevra: One Parameter Instead of a Selector List
Browsevra folds all four dismissal techniques, plus the wait-then-act timing logic, behind a single request option instead of asking you to ship and maintain your own CMP rule database. Set a consent-handling flag and the rendering engine detects known CMP fingerprints, waits for the banner to fully render, attempts cookie injection or a reject click where appropriate, and strips any remaining overlay or scroll-lock artifacts before returning your screenshot, PDF, or extracted HTML.
POST /v1/render
{
"url": "https://example.com",
"format": "screenshot",
"fullPage": true,
"dismissConsent": true
}
{
"status": "success",
"consentHandled": true,
"cmpDetected": "OneTrust",
"screenshotUrl": "https://cdn.browsevra.com/renders/abc123.png"
}
That's a GDPR-aware screenshot API capture without a single hardcoded selector on your end — the same parameter works whether you're pulling a screenshot, generating a PDF, or feeding clean HTML into a structured data extraction pipeline where banner copy would otherwise pollute your parsed fields.
Frequently Asked Questions
Why does my screenshot API still show the cookie banner even after I added a delay?
A delay only addresses load timing, not detection or dismissal — the banner still renders, you're just waiting for it. If nothing actively identifies the CMP and clicks or removes it, the banner will render and remain, whether you wait 500ms or 5 seconds; a longer delay can even capture a fully-settled, more visible overlay.
Does clicking 'reject' on a banner count as GDPR-compliant automated consent, or does it just hide the UI?
Clicking reject simply hides the UI element for capture purposes — it doesn't constitute a legally meaningful consent decision, since GDPR consent is meant to reflect a real user's choice, not an automated script's. For scraping and rendering, the goal is a clean capture, not a legal consent record, so treat the click as a UI-dismissal mechanism rather than a compliance action.
Can a display:none CSS rule reliably remove all cookie banners?
No — CSS suppression hides many banners visually but doesn't reliably handle every case. Iframe-hosted consent walls, shadow-DOM banners, and body-level scroll-lock classes often persist untouched by a simple display:none override, leaving layout artifacts even when the visible box disappears.
How do I know which consent management platform a target site is using before writing a selector?
Check the page for known container IDs and script sources — OneTrust typically uses onetrust-banner-sdk, Cookiebot uses CybotCookiebotDialog, and TCF-compliant sites expose a __tcfapi function you can call directly. Automated CMP fingerprinting, checking for these known signatures, is more reliable than assuming any single vendor's markup.
Is it legal/safe to auto-click 'accept' vs 'reject' on someone else's site when scraping at scale?
Auto-clicking 'reject' is generally the safer default for automated capture, since it declines optional tracking rather than granting it, and most jurisdictions' scraping and privacy concerns center on data collection rather than banner interaction. Neither click constitutes legal consent on behalf of a real visitor; the practical goal for developers is a clean capture, and 'reject' minimizes any question about tracking data being generated during automated rendering.
Stop maintaining a selector list for every CMP vendor you encounter. Add dismissConsent to your request, grab a free API key, check the docs for the full parameter reference, and see usage limits on pricing — or just start testing at browsevra.