A GPAL selector is not a single CSS string -- it is a strategy chain. You define as many matching approaches as you want; GPAL tries them in order and uses the first element that matches. When a site redesign renames a class, a fallback XPath or text match keeps the workflow alive without a code change. Persistent selectors register a handler once and re-evaluate it automatically on every page interaction for the rest of the session -- the right tool for cookie banners, CAPTCHA intercepts, and any nag that can appear at any time. See The Selector System, Match Criteria & Filtering, Fallback Actions: Automatic Recovery on Error, and Persistent Selectors: Handling Nags and Popups.
// Multi-strategy fallback -- tried in order, first match wins
var price = GPAL
// Persistent: dismiss a cookie banner for the entire session
var cookieBanner = GPAL
els[0]
return CallIfStatus
})
GPAL
Register a WithPersistentSelector with a CAPTCHA or block-page selector to catch soft blocks -- pages that return HTTP 200 but deliver a challenge instead of data. CallIfFound fires whenever the element is present, so your workflow can log a warning, pause, or escalate rather than silently extracting garbage.
CSS class renames and DOM restructuring are the most common source of silent scraper failures. GetLLMDigest extracts content semantically -- you describe what you want in plain language and the model finds it regardless of how the underlying HTML is structured. This makes LLMDigest the right choice for any field whose CSS path is likely to change. For a more targeted approach, LLMDigestRules.yaml lets you fine-tune extraction rules without touching workflow code. For Next.js and React sites, GetHydratedData pulls structured data directly from the hydration payload, bypassing the DOM entirely. GetPageSource with System.IO.File.WriteAllText gives you a raw HTML archive -- if your extraction logic improves later, you can re-parse historical captures without re-scraping. See LLM-Ready Page Digests and Tuning LLMDigestRules.yaml.
// Selector-based extraction breaks when the
// CSS class is renamed -- a structural change
// on the server silently empties your data
//
// LLMDigest extracts by meaning, not structure:
LLMDigestResult digest;
GPAL
// digest
// regardless of how the page HTML is organized
// Raw HTML capture for re-processing later:
string html;
GPAL
System
StealthType is a bitmask -- you combine only the flags your target actually requires rather than applying everything at once. CDP suppresses automation signals at the DevTools level. GoogleReferrer makes the visit look like a search result click. PatchDriver strips automation markers from the driver binary itself. WithUseAutomationEngine is another resilience lever: if one engine gets blocked, switching to another changes the fingerprint of the session without changing any workflow logic. Beyond evasion, GPAL named-constant structs accept freehand values so configuration is never locked to a fixed set. WaitFor accepts both named WaitTime constants such as Forever and Immediate and any raw millisecond value. WithModel and WithProvider accept both GPAL-defined names and any freehand identifier, so new AI models and providers work without a GPAL update. See Stealth Techniques - Controlling What the Browser Reveals and Named-Constant Structs: An Enum That Also Takes Freehand Values.
// Combine stealth flags as needed
GPAL
StealthType
StealthType
StealthType
// Swap the automation engine without touching anything else
GPAL
// Named-constant structs accept freehand values:
// WaitTime has named constants and accepts raw ms
GPAL
GPAL
// AI models are freehand strings -- no update needed
GPAL
No single technique covers every scenario. A real resilience strategy combines them: a multi-strategy selector for structural drift, a persistent CAPTCHA handler for soft blocks, LLMDigest for fields prone to CSS churn, and the right stealth flags for the target site. GPAL is designed so these layers compose naturally without interfering with each other.
Showing off some plain text in these paragraphs eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo veniam mollitia excepturi animi eum illum non libero sapiente provident assumenda, delectus voluptatum nobis sed dolorem adipisci laudantium incidunt. Error, ratione?
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo veniam mollitia excepturi animi eum illum non libero sapiente provident assumenda, delectus voluptatum nobis sed dolorem adipisci laudantium incidunt. Error, ratione?
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo veniam mollitia excepturi animi eum illum non libero sapiente provident assumenda, delectus voluptatum nobis sed dolorem adipisci laudantium incidunt. Error, ratione?
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo veniam mollitia excepturi animi eum illum non libero sapiente provident assumenda, delectus voluptatum nobis sed dolorem adipisci laudantium incidunt. Error, ratione?
Here you can find different accents and emphasis sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
This is a link and how it could look like bestlinkinthebeautifulworld. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Here's just some classic bold text adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam notBoldSecondbestlinkinthebeautifulworld illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Obcaecati, iste distinctio veritatis eligendi laboriosam adipisicing elit illo nostrum corporis at adipisicing elit libero vel voluptas? Expedita, adipisicing facere dolores voluptatem ad ab rem assumenda soluta!
Other cuple of colors in case we want to emphasize several ways adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam adipisicing elit illo nostrum corporis at voluptatem libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta! Lorem ipsum dolor, sit amet consectetur adipisicing elit. Quod veniam, quam ad expedita laborum sed at voluptates culpa ipsam ut vel. Ullam temporibus a mollitia quod aliquam ratione exercitationem nesciunt.
Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta! Lorem ipsum dolor, sit amet consectetur adipisicing elit. Quod veniam, quam ad expedita laborum sed at voluptates culpa ipsam ut vel. Ullam temporibus a mollitia quod aliquam ratione exercitationem nesciunt.
Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Lorem ipsum dolor sit amet consectetur adipisicing elit. Repudiandae quas consequuntur illo numquam assumenda autem exercitationem distinctio perspiciatis in natus. Eius dicta similique ipsam ipsa minima, nemo quae enim tempore.
GPAL
.CallIfNotFound(GenericCallIfNotFound)
.WithPublishToConsole();
//System.Drawing.Rectangle windowSize = new System.Drawing.Rectangle(10, 10, 1500, 1024);
// NOTE: we have to set browser = before we execute any steps
// this is due to the 'GenericCallIfNotFound' which might throw an exception, and BankScraper will not have the browser set when it calls scraper.Close()
// until the complete fluent line gets executed (meaning every step, meaning browser is not set until everything else succeeds)
browser = GPAL.Browser
.WithBrowserType(Enums.BrowserType.Chrome)
.WithProfileDataDirectory(ChromeProfileLocation)
.WithUseAutomationEngine(AutomationEngine.Selenium)
.WithWindowSize(new System.Drawing.Rectangle(0,0,1920,1080))
.ToGPALObject();