Platform-Specific Browser Automation
Use when automating specific platforms that have unique anti-bot measures or DOM structures. Each platform entry is a live-verified pattern.
Support files (shared with browser-automation):
references/skool-selectors.md— Live-verified Skool.com selectors, signup flow, anti-detection notesreferences/reddit-anti-bot.md— Reddit's multi-layer anti-bot system: JS challenge, closed shadow DOM SSO buttons, CDP piercing via Playwright, domain strategy, rate limitsreferences/curl-cffi-tls-impersonation.md— curl_cffi: TLS impersonation for headless HTTP (Chrome/Safari fingerprints), Reddit case study, when to skip browser entirely
Skool.com Signup Flow (Verified May 2026)
- Landing page at
skool.com/signupshows no form — just a "Create your community" button - Clicking the button opens a modal with:
#first_name,#last_name,#email,#password - Submit button:
button[type='submit']with text "Sign Up", initiallydisableduntil form validates - No Cloudflare challenge on direct connection (residential IP from WSL)
- After submit: redirects/prompts for email verification
Skool uses React/Next.js with dynamic selectors. CSS selectors may need updating if they change their UI. Run headless=False first to verify the flow.
Reddit Anti-Bot Strategy
Reddit employs multiple detection layers:
- JS challenge timing: Reddit serves a challenge page before the real content. Timing matters.
- Closed shadow DOM SSO buttons: Web components with closed shadow roots hide interactive elements from standard DOM queries.
document.querySelectorAll,get_by_text, CSS piercing>>>, and manualshadowRootwalks all fail on closed shadow DOM. - CDP piercing via Playwright: The fix is CDP via
context.new_cdp_session(page)withDOM.performSearch({includeUserAgentShadowDOM: True}). Always checkresultCountbefore callinggetSearchResults— a count of 0 causes "Invalid search result range". - Domain selection: old.reddit blocks Chrome TLS; www.reddit.com works headless.
- Rate limits: ~4 attempts before rate-limiting kicks in.
Headless detection warning: networkidle hangs on Reddit — SPA maintains constant websocket/polling connections. Use wait_until="domcontentloaded" or wait_until="commit" with a fixed wait instead.
curl_cffi TLS Impersonation
When to skip browser entirely — curl_cffi provides TLS-level impersonation for headless HTTP requests:
- Supports Chrome and Safari TLS fingerprints
- 100x lighter than launching a browser
- Use when the target site doesn't require JavaScript for the data you need
Decision heuristic: re.findall(r'<form', html) — if no forms exist in raw HTML, the login is JS-rendered and you need a real browser. If forms are present, curl_cffi can handle it.
Live-Platform Selector Discovery
When automating a site you haven't tested live, CSS selectors are guesses. Two-phase approach:
Phase 1: Headless reconnaissance — Launch headless, navigate to target, dump all input/button attributes:
page.goto("https://target.com/signup", wait_until="networkidle")
time.sleep(3)
inputs = page.locator("input").all()
for i in inputs:
attrs = page.evaluate('''(el) => {
const r = {};
for (const a of el.attributes) r[a.name] = a.value;
return r;
}''', i.element_handle())
print(attrs)
Phase 2: Flow discovery — Modern SPAs hide forms behind CTAs. Click buttons, wait for modals, re-check the DOM:
page.locator("button:has-text('Get Started')").first.click()
time.sleep(3)
# Now check for inputs again — they may appear in a modal
Pitfalls
- Try HTTP before browser: Before reaching for Playwright or browser-use, test if the target site's login is a simple form POST. Use
curl_cffiwith TLS impersonation for sites that don't require JavaScript for their login flow. - Headless detection by target sites: Some sites (Reddit, Cloudflare-protected) detect and block headless Chromium even with stealth flags. Always confirm it's not an IP block first:
curl -sI https://target.com. If curl gets 200/301 but headless Chromium gets blocked, the block is fingerprint-level. Try--headless=newflag, a residential proxy, or fall back tocurl_cffi. - Closed shadow DOM (Reddit, modern SPAs): Web components with closed shadow roots hide interactive elements. Use CDP with
includeUserAgentShadowDOM: True.