9.5 KiB
Convenciones del proyecto web_scraping
Reglas operativas para todo control de navegador y extracción web del proyecto. Aplican a la app
script_navegador, a los scripts YAML y a cualquier función del dominio browser que se use desde
aquí. Construido 100% sobre Linux nativo (sin WSL/Windows).
Nota: estas son convenciones (cómo se trabaja), no datos. Los datos extraídos (pliegos, RFPs, listados) van en
vaults/cuando empecemos a capturar.
1. Tamaño de ventana fijo
Todo navegador se lanza con un tamaño de ventana explícito y estable. Por defecto 1366x768
(resolución de portátil muy común → menos sospechosa que un viewport raro).
- Motivo: reproducibilidad de selectores/screenshots y menor superficie de fingerprinting (un viewport común y consistente es menos señalable que uno aleatorio por sesión).
- Implementación:
script-navegador launch --width 1366 --height 768(flags--window-sizea Chrome). Nunca lanzar sin tamaño definido.
2. Carpeta de usuario dedicada del proyecto
Siempre se define un user-data-dir propio del proyecto, nunca el perfil real del usuario por
defecto (evita locks y contaminación de la sesión personal).
- Ruta por defecto:
~/.local/share/web_scraping/chrome-profile. - Implementación:
script-navegador launch --profile <dir>(default ya apunta ahí). - El perfil es persistente entre ejecuciones (cookies, login, estado de extensiones).
3. Flujo headless: primero visible, luego headless
Se empieza desarrollando con ventana visible (headless=false) para ver lo que pasa y depurar
selectores junto al humano. Solo cuando un flujo está estandarizado y probado se pasa a
headless=true para correrlo desatendido/en lote.
- Default de
launch:headless=false. - Promoción a headless: pasar
--headlessuna vez el script YAML del flujo es estable.
4. Esperas inteligentes + pequeños sleeps aleatorios
Nunca sleep ciegos fijos como mecanismo de sincronización. Se espera a condiciones reales:
readyState=complete(cdp_wait_load).- Red en reposo (
cdp_wait_idle): nº de peticiones HTTP/WS en vuelo == 0 durante N ms (señal "network idle"). Es inmune a extensiones que mutan el DOM y a animaciones JS. Timeout corto (8s) porque páginas con polling/websockets persistentes pueden no llegar nunca a 0. - Selector presente (
cdp_wait_element).
Sobre esas esperas se añaden micro-pausas aleatorias < 500 ms (jitter) entre acciones, para
imitar el ritmo humano (anti-detección). El random es complemento, no sustituto, de la espera real.
Histórico:
cdp_wait_idleusó al principio la longitud deinnerHTMLcomo señal de quietud, pero con extensiones como Dark Reader (que reinyecta estilos sin parar) el DOM nunca se estabilizaba y la espera agotaba siempre el timeout. Por eso se migró a network-idle.
5. Captura de datos vía extensión mitm (web_proxy)
El tráfico se puede capturar con la infraestructura web_proxy (mitmproxy + extensión de toggle
ya presente en /etc/chromium.d/). Por eso los navegadores se lanzan con --keep-extensions
(no --disable-extensions): la extensión de captura debe seguir cargada.
- mitmweb corre en
127.0.0.1:8081; el proxy de captura en:8889. - Las capturas rotan a
~/captures(verrotate_capture_flows.py). - El toggle del proxy es per-perfil; activarlo en el perfil del proyecto cuando se quiera capturar.
6. Movimientos de ratón + clics realistas
Las interacciones (click, drag) deben simular trayectorias humanas (curvas, aceleración, micro-
desvíos), no saltos instantáneos a coordenadas. Stack decidido: Go puro — curvas Bézier sobre
Input.dispatchMouseEvent como funciones del registry (cdp_move_mouse_human, cdp_click_human),
sin dependencias externas. Integrado y por defecto (script_navegador v0.2.0): el comando click y
la acción click del runner YAML usan Bézier sin pedir nada. Opt-out con --instant (CLI) o
instant: true (paso YAML) cuando el elemento no tiene bounding box visible y conviene el click directo.
7. Proxys rotativos (Decodo) — futuro
Más adelante se integrarán proxys residenciales rotativos con Decodo (antes Smartproxy) para
distribuir las peticiones y evitar bloqueos por IP. Pendiente de implementar (ver
## Pendientes).
8. CDP siempre activo en el navegador del usuario — futuro / decisión de seguridad
Objetivo: poder usar las capacidades de automatización sobre el chromium que el usuario usa a
diario mientras navega, modificando el launcher (/etc/chromium.d/) para que todo chromium
nazca con CDP activado.
APLICADO (2026-06-05): fragmento /etc/chromium.d/cdp con
--remote-debugging-port=9222 --remote-allow-origins=*, sin --remote-debugging-address=0.0.0.0
→ el puerto bindea solo en loopback (127.0.0.1), no accesible desde la red. Todo chromium que el
usuario abra a partir de ahora nace con CDP. (El chromium ya abierto antes del cambio no tiene CDP
hasta reiniciarlo.)
Reproducible entre PCs con la función del registry apply_chromium_cdp_flag_bash_browser (no
editar el fragmento a mano):
fn run apply_chromium_cdp_flag # escribe /etc/chromium.d/cdp (loopback 9222, idempotente)
fn run apply_chromium_cdp_flag --dry-run # previsualiza sin tocar nada
fn run apply_chromium_cdp_flag --remove # desactiva CDP global
# --network añade --remote-debugging-address=0.0.0.0 (expone a la red: riesgo, ver Gotchas)
Coordinación de puertos: el chromium diario ocupa el 9222 global. Para sesiones de automatización con perfil dedicado, lanzar en OTRO puerto:
script-navegador launch --port 9333. Dos procesos chromium no pueden compartir el mismo--remote-debugging-port.
⚠️ Implicación de seguridad: con CDP abierto, cualquier proceso local del usuario puede controlar el navegador y leer cookies/sesiones autenticadas. El bind solo-local evita acceso desde la red, pero NO protege de procesos locales. Aceptado conscientemente para este equipo de un solo usuario. No replicar en máquinas compartidas/multiusuario.
9. Perfiles nuevos: solo uBlock Origin Lite
Al preparar un perfil de usuario nuevo para automatización (clonando del perfil real del
usuario), se conserva únicamente uBlock Origin Lite (ddkjiahejlhfcafbddmgiahcphecmpfh) y se
eliminan el resto de extensiones del usuario.
- Motivo: uBlock reduce ruido (anuncios, trackers) → páginas más limpias y rápidas de scrapear.
Las demás estorban la automatización:
- Dark Reader: reinyecta estilos sin parar → rompe esperas por DOM y oscurece screenshots.
- NoScript: bloquea JavaScript → rompe SPAs y scraping de contenido dinámico.
- OneTab: interfiere con la gestión de pestañas.
- La extensión de captura
web_proxyes aparte: se carga globalmente vía/etc/chromium.d/(no es una extensión del perfil), por lo que esta regla no la toca. uBlock + web_proxy conviven.
Dos mecanismos (sistema + clonado)
-
Política de sistema (primario) —
/etc/chromium/policies/managed/extensions.jsonconExtensionInstallForcelistfuerza la instalación de extensiones en cualquier perfil de chromium del equipo. Reducido el 2026-06-05 a solo uBlock Origin Lite (ddkjiahejlhfcafbddmgiahcphecmpfh). Antes forzaba 4 (uBlock + Dark Reader + NoScript + OneTab). Esto garantiza que todo perfil nuevo —lo cree quien lo cree— nazca solo con uBlock, sin pasos extra. Backup del original enextensions.json.bak.20260605.-
⚠️ Afecta también el perfil diario del usuario: al reiniciar chromium, las extensiones que ya no están en la forcelist se desinstalan.
-
Editar requiere
sudo(pass claude/sudo). -
Reproducible entre PCs con la función del registry
apply_chromium_extension_policy_bash_browser(no editar el JSON a mano): escribe la forcelist de forma idempotente con backup automático.# Forzar solo uBlock Origin Lite en todos los perfiles fn run apply_chromium_extension_policy --keep ddkjiahejlhfcafbddmgiahcphecmpfh fn run apply_chromium_extension_policy --keep ddkjiahejlhfcafbddmgiahcphecmpfh --dry-run
-
-
Clonado con filtro (secundario) —
prepare_chrome_profile --src ~/.config/chromium --dst <perfil_proyecto>clona un perfil existente (cookies, sesiones) conservando solo la whitelist de extensiones (--keep <id>, default uBlock). Útil cuando se quiere arrancar de una copia del perfil real; la base de extensiones ya la garantiza la política de sistema.
Pendientes (decisiones abiertas)
| # | Tema | Estado |
|---|---|---|
| 7 | Proxys rotativos con Decodo | Futuro, sin empezar |
Estado de implementación
| Regla | Estado | Dónde |
|---|---|---|
| 1. Tamaño de ventana fijo | ✅ | script-navegador launch --width/--height (default 1366x768) |
| 2. Carpeta de usuario del proyecto | ✅ | --profile (default ~/.local/share/web_scraping/chrome-profile) |
| 3. Flujo headless visible→true | ✅ convención | launch default headless=false |
| 4. Esperas inteligentes + jitter | ✅ | cdp_wait_load+cdp_wait_idle (network-idle)+jitter() |
| 5. Captura mitm | ✅ infra | --keep-extensions + web_proxy |
| 6. Ratón/clics realistas | ✅ | cdp_move_mouse_human + cdp_click_human; default en script-navegador click y runner YAML (opt-out --instant / instant: true) |
| 7. Proxys rotativos Decodo | ⏳ | futuro |
| 8. CDP global en chromium usuario | ✅ | /etc/chromium.d/cdp aplicado (loopback 9222) |
| 9. Perfiles nuevos solo uBlock | ✅ | prepare_chrome_profile --src ~/.config/chromium --dst <perfil> |