2026-08-07 — marvelousdb: Cloudflare Browser Run como fuente de imagenes

Contexto: el usuario pregunto si la “scraper tool de Cloudflare” puede servir como alternativa a SerpAPI para cachear imagenes de personajes.

Datos frescos (docs 2026, verificados via webfetch)

  • Producto actual: Browser Run (antes Browser Rendering). Quick Actions (sin desplegar codigo) + Browser Sessions (Playwright/Puppeteer/CDP).
  • Workers Free: 10 min de navegador/dia, 1 Quick Action cada 10s, timeout 60s. ~100-200 busquedas de imagenes/dia gratis.
  • Workers Paid: 10h/mes incluidas, luego $0.09/h.
  • IMPORTANTE: “Requests from Browser Run will always be identified as a bot” → Google bloquea; DuckDuckGo Images es el target viable.
  • Endpoint /scrape: POST a api.cloudflare.com/client/v4/accounts//browser-rendering/scrape con {url, gotoOptions:{waitUntil:‘networkidle2’}, elements:[{selector}]}. Token con permiso “Browser Rendering - Edit”.

Implementacion (data/cache-images.js)

  • Nueva pasada --browserrun: scrapea duckduckgo.com/?q=<name> comic character&iax=images&ia=images con selector configurable (default img.tile--img__img), toma el primer src http, descarga con validacion de magic bytes.
  • Config en .env: CLOUDFLARE_ACCOUNT_ID, CLOUDFLARE_API_TOKEN, CLOUDFLARE_BROWSER_RUN_SELECTOR (opcional).
  • Rate: sleep 10s (Quick Actions free: 1/10s). En 429: mensaje claro y break (cuota diaria agotada).
  • Bug evitado: validar credenciales UNA vez al inicio de la pasada (antes fallaba por personaje y se colgaba 10s x cada uno).
  • Orden de fuentes: —fandom → —commons → —browserrun → SerpAPI.

Verificacion

  • 21/21 tests. Sin credenciales da mensaje claro y sale rapido.
  • El usuario debe crear el token y probar; si DDG cambia selectores, ajustar CLOUDFLARE_BROWSER_RUN_SELECTOR.

Pendiente (usuario)

  • Crear API token con permiso Browser Rendering - Edit, poner credenciales en .env, correr npm run cache:images -- --browserrun (los 424 faltantes caben en ~3-4 dias del free tier).

ACTUALIZACION (prueba real con credenciales del usuario)

  • Las credenciales que el usuario pego tenian basura de pegado en .env (t=162ab... en ACCOUNT_ID y ==cfat... en el token) → corregidas.
  • Token verificado con /tokens/verify: “valid and active”.
  • Endpoint /scrape funciona: {"success":true,"result":[...]}.
  • Selectores descubiertos de DDG Images (2026): el HTML no trae las imagenes en crudo y el selector viejo img.tile--img__img ya no existe. Las imagenes reales vienen en //external-content.duckduckgo.com/iu/?u=... (thumbnails de Bing) y los favicons en /ip3/. Fix: selector generico img con limit:40 + filtro /iu/?u= y exclusion /ip3/, URL absoluta con https:.
  • 429: distinguir rate limit (Retry-After ⇐ 60 → esperar y reintentar el mismo personaje) de cuota diaria (Retry-After > 60 → break). El primer 429 era del rate de 10s (mis curls de prueba), no de cuota.
  • 422 para queries con comillas → sanitizar comillas de la query.
  • TDZ: BROWSER_RUN_SELECTOR declarada despues de main().catch() → movida arriba.
  • RESULTADO: 4 personajes cacheados en un run de prueba (los que Fandom y Commons no pudieron): Ghost Exterminator, Hiergargo, Olive the Other Reindeer, Phantom Princess. JPEGs validos (magic bytes ok).
  • Faltantes: 420. Free tier ~10 min/dia → completar en ~3 dias con npm run cache:images -- --browserrun (o —limit 100/dia).