SPB Git forge

spb/fetcha

Public
11commits 1branches 0releases
1.5 MBsize
maindefault branch
16 days agolast push
TypeScript 97.5% SQL 1.4% Python 0.8%

browser: never block anti-bot verification assets (/cdn-cgi trace pixels, widget assets); escalated renders load every asset

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Simon-Pierre Boucher committed 16 days ago (Sep 8, 2026) parent 23a4b63

2 changed files +7 −2

modified packages/browser/src/index.ts +4 −1
@@ -106,6 +106,9 @@ export interface BrowserStatus {
106 106 captchaSolver: { provider: string; requested: number; solved: number; failed: number; spentUsd: number; lastError: string | null } | null;
107 107 }
108 108
109 +/** Assets that anti-bot vendors use to verify a real browser (trace pixels, widget assets): never block them. */
110 +const ANTIBOT_ASSET_RE = /\/cdn-cgi\/|challenges\.cloudflare\.com|captcha-delivery\.com|datadome|perimeterx|px-cdn|px-cloud|kasada|kpsdk|imperva|incapsula|_Incapsula_Resource|hcaptcha\.com|recaptcha|gstatic\.com\/recaptcha|arkoselabs|funcaptcha|awswaf|distil|shape-security|vercel\.com\/_vercel|\/_vercel\/|akamaihd|akam\/|\/akam\//i;
111 +
109 112 const CHALLENGE_SELECTORS = ["#challenge-running", "#challenge-form", "#challenge-stage", ".cf-turnstile", "iframe[src*='challenges.cloudflare.com']", "#px-captcha", "#datadome", "iframe[src*='captcha-delivery.com']", "#sec-cpt-if", "form#challenge", "#cmsg", "[data-testid='challenge']"];
110 113
111 114 export class BrowserPool {
@@ -386,7 +389,7 @@ export class BrowserPool {
386 389 // fallback() (not continue()) lets Patchright's context-level route inject the init scripts.
387 390 return route.fallback();
388 391 }
389 if (blockResources) {
392 + if (blockResources && !ANTIBOT_ASSET_RE.test(r.url())) {
390 393 const type = r.resourceType();
391 394 if (type === "image" || type === "media" || type === "font" || type === "manifest" || type === "texttrack") return route.abort("blockedbyclient");
392 395 }
modified packages/routing/src/executor.ts +3 −1
@@ -224,7 +224,9 @@ export class FetchExecutor {
224 224 waitFor: request.wait_for ?? null,
225 225 waitMs: request.wait_ms ?? null,
226 226 javascript: request.javascript !== false,
227 blockResources: request.block_resources,
227 + // A site that already blocked us (or is known to need the browser) gets every asset: anti-bot
228 + // verification checks that images/fonts really load.
229 + blockResources: request.block_resources && !browserEscalated && !knowledgeSaysBrowser,
228 230 screenshot: request.screenshot,
229 231 solveCaptcha: request.solve_captcha,
230 232 maxResponseBytes: maxBytes,
231 233