Initial commit: navegator - Chrome CDP automation for LLMs
Add complete navegator system for stealthy browser automation: - CDP client with WebSocket communication - Browser API with navigation, storage, network, runtime - Stealth flags and anti-detection scripts - Persistent profile support - Examples and comprehensive documentation Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,396 @@
|
||||
# Binarios de Automatización - Navegator
|
||||
|
||||
Herramientas CLI standalone para automatizar navegación web.
|
||||
|
||||
## 🎯 Características Principales
|
||||
|
||||
✅ **Perfiles Personalizables**: Cada binario puede usar cualquier perfil
|
||||
✅ **Cookies Separadas**: Simula usuarios diferentes sin conflictos
|
||||
✅ **Sin Dependencias**: Solo el binario ejecutable
|
||||
✅ **Output Estructurado**: JSON, PNG, logs
|
||||
✅ **Stealth Completo**: Flags anti-detección incluidas
|
||||
|
||||
---
|
||||
|
||||
## 📦 Binarios Disponibles
|
||||
|
||||
### 1. `screenshot` - Captura de Pantalla
|
||||
|
||||
Captura screenshots de cualquier página web.
|
||||
|
||||
```bash
|
||||
# Compilar
|
||||
go build -o screenshot cmd/screenshot.go
|
||||
|
||||
# Uso básico
|
||||
./screenshot -url https://example.com
|
||||
|
||||
# Con perfil específico
|
||||
./screenshot -url https://github.com -profile mi-usuario -o github.png
|
||||
|
||||
# Página completa, modo visible
|
||||
./screenshot -url https://news.ycombinator.com -full=true -headless=false
|
||||
|
||||
# Resolución personalizada
|
||||
./screenshot -url https://google.com -width=1920 -height=1080 -o google_hd.png
|
||||
```
|
||||
|
||||
**Parámetros:**
|
||||
- `-url` (requerido): URL a capturar
|
||||
- `-profile` (default: screenshot-bot): Perfil de navegador
|
||||
- `-o` (default: screenshot.png): Archivo de salida
|
||||
- `-headless` (default: true): Modo headless
|
||||
- `-full` (default: false): Captura página completa
|
||||
- `-width` (default: 1280): Ancho de ventana
|
||||
- `-height` (default: 720): Alto de ventana
|
||||
|
||||
---
|
||||
|
||||
### 2. `buscar` - Motor de Búsqueda
|
||||
|
||||
Busca en DuckDuckGo y extrae resultados estructurados.
|
||||
|
||||
```bash
|
||||
# Compilar
|
||||
go build -o buscar cmd/buscar.go
|
||||
|
||||
# Uso básico
|
||||
./buscar -q "golang tutorial"
|
||||
|
||||
# Con perfil y más resultados
|
||||
./buscar -q "python web scraping" -n 20 -profile researcher-bot
|
||||
|
||||
# Guardar en JSON
|
||||
./buscar -q "nodejs frameworks" -output resultados.json
|
||||
|
||||
# Modo visible para debugging
|
||||
./buscar -q "react hooks" -headless=false -profile dev-session
|
||||
```
|
||||
|
||||
**Parámetros:**
|
||||
- `-q` (requerido): Consulta de búsqueda
|
||||
- `-profile` (default: search-bot): Perfil de navegador
|
||||
- `-n` (default: 10): Número máximo de resultados
|
||||
- `-output` (opcional): Guardar resultados en JSON
|
||||
- `-headless` (default: true): Modo headless
|
||||
|
||||
**Output JSON:**
|
||||
```json
|
||||
[
|
||||
{
|
||||
"titulo": "Tutorial de Golang",
|
||||
"url": "https://...",
|
||||
"descripcion": "Aprende Go desde cero..."
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. `navegar` - Navegación Interactiva
|
||||
|
||||
Navega a URLs, interactúa con elementos, y registra acciones.
|
||||
|
||||
```bash
|
||||
# Compilar
|
||||
go build -o navegar cmd/navegar.go
|
||||
|
||||
# Navegación simple
|
||||
./navegar -url https://example.com -profile usuario1
|
||||
|
||||
# Con click en elemento
|
||||
./navegar -url https://github.com -click "a[href='/explore']" -profile dev1
|
||||
|
||||
# Llenar formulario
|
||||
./navegar -url https://httpbin.org/forms/post \
|
||||
-type "input[name='custname']" \
|
||||
-text "Juan Pérez" \
|
||||
-profile test-user
|
||||
|
||||
# Mantener abierto más tiempo
|
||||
./navegar -url https://reddit.com -duration 30 -headless=false -profile lurker
|
||||
|
||||
# Sesión completa con recording
|
||||
./navegar -url https://example.com \
|
||||
-profile session-abc \
|
||||
-click "button.primary" \
|
||||
-duration 15
|
||||
```
|
||||
|
||||
**Parámetros:**
|
||||
- `-url` (requerido): URL a visitar
|
||||
- `-profile` (default: user-default): Perfil de navegador
|
||||
- `-click` (opcional): Selector CSS para hacer click
|
||||
- `-type` (opcional): Selector CSS donde escribir
|
||||
- `-text` (opcional): Texto a escribir (requiere -type)
|
||||
- `-headless` (default: false): Modo headless
|
||||
- `-duration` (default: 10): Segundos que mantener abierto
|
||||
|
||||
**Genera:** `recording_<profile>.log` con todas las acciones
|
||||
|
||||
---
|
||||
|
||||
## 🎭 Simulación de Usuarios Orgánicos
|
||||
|
||||
### Concepto de Perfiles
|
||||
|
||||
Cada perfil es un **usuario virtual independiente**:
|
||||
|
||||
```
|
||||
perfiles/
|
||||
├── usuario-juan/ # Juan - desarrollador
|
||||
├── usuario-maria/ # Maria - diseñadora
|
||||
├── bot-research-1/ # Bot de investigación #1
|
||||
├── bot-research-2/ # Bot de investigación #2
|
||||
└── session-temp/ # Sesión temporal
|
||||
```
|
||||
|
||||
Cada perfil mantiene:
|
||||
- ✅ Cookies propias
|
||||
- ✅ LocalStorage separado
|
||||
- ✅ Historial independiente
|
||||
- ✅ Cache aislado
|
||||
- ✅ User-Agent persistente
|
||||
|
||||
### Ejemplo: Múltiples Usuarios
|
||||
|
||||
```bash
|
||||
# Usuario 1: Busca tutoriales de Go
|
||||
./buscar -q "golang tutorial" -profile dev-juan -n 10
|
||||
|
||||
# Usuario 2: Busca Python
|
||||
./buscar -q "python basics" -profile student-maria -n 15
|
||||
|
||||
# Usuario 3: Captura diseños
|
||||
./screenshot -url https://dribbble.com -profile designer-pedro
|
||||
|
||||
# Reutilizar perfil de Juan (tiene sus cookies)
|
||||
./navegar -url https://github.com -profile dev-juan
|
||||
```
|
||||
|
||||
### Script de Demostración
|
||||
|
||||
```bash
|
||||
./ejemplos_perfiles.sh
|
||||
```
|
||||
|
||||
Simula 3 usuarios diferentes navegando automáticamente.
|
||||
|
||||
---
|
||||
|
||||
## 🔄 Casos de Uso
|
||||
|
||||
### 1. Monitoreo Multi-Cuenta
|
||||
```bash
|
||||
# Revisar 5 cuentas diferentes
|
||||
for i in {1..5}; do
|
||||
./navegar -url https://miapp.com/dashboard \
|
||||
-profile account-$i \
|
||||
-duration 5
|
||||
done
|
||||
```
|
||||
|
||||
### 2. A/B Testing
|
||||
```bash
|
||||
# Probar con diferentes perfiles (cookies diferentes)
|
||||
./screenshot -url https://miapp.com -profile user-a -o version-a.png
|
||||
./screenshot -url https://miapp.com -profile user-b -o version-b.png
|
||||
```
|
||||
|
||||
### 3. Scraping Distribuido
|
||||
```bash
|
||||
# Buscar desde múltiples "usuarios"
|
||||
./buscar -q "keyword1" -profile bot-1 -output bot1.json &
|
||||
./buscar -q "keyword2" -profile bot-2 -output bot2.json &
|
||||
./buscar -q "keyword3" -profile bot-3 -output bot3.json &
|
||||
wait
|
||||
```
|
||||
|
||||
### 4. Testing de Sesiones
|
||||
```bash
|
||||
# Login con usuario A
|
||||
./navegar -url https://app.com/login \
|
||||
-type "#username" -text "userA" \
|
||||
-profile session-a
|
||||
|
||||
# Verificar que usuario B no tiene acceso
|
||||
./navegar -url https://app.com/dashboard \
|
||||
-profile session-b
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🐍 Integración con Python
|
||||
|
||||
```python
|
||||
import subprocess
|
||||
import json
|
||||
|
||||
# Buscar desde Python con perfil específico
|
||||
result = subprocess.run([
|
||||
'./buscar',
|
||||
'-q', 'python tutorial',
|
||||
'-n', '10',
|
||||
'-profile', 'python-bot',
|
||||
'-output', 'temp.json'
|
||||
], capture_output=True, text=True)
|
||||
|
||||
# Parsear resultados
|
||||
with open('temp.json') as f:
|
||||
results = json.load(f)
|
||||
for r in results:
|
||||
print(f"{r['titulo']}: {r['url']}")
|
||||
|
||||
# Screenshot con perfil rotativo
|
||||
profiles = ['user1', 'user2', 'user3']
|
||||
for i, profile in enumerate(profiles):
|
||||
subprocess.run([
|
||||
'./screenshot',
|
||||
'-url', 'https://example.com',
|
||||
'-profile', profile,
|
||||
'-o', f'capture_{i}.png'
|
||||
])
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🛡️ Stealth y Anti-Detección
|
||||
|
||||
Todos los binarios incluyen automáticamente:
|
||||
|
||||
✅ `navigator.webdriver = false`
|
||||
✅ Sin banners de "controlado por automatización"
|
||||
✅ Headers realistas
|
||||
✅ Timing humano en Type
|
||||
✅ User-Agent personalizable
|
||||
✅ Sin extensiones sospechosas
|
||||
|
||||
Para máximo stealth:
|
||||
```bash
|
||||
# Usar modo visible (menos detectable)
|
||||
./navegar -url https://sitio-estricto.com -headless=false -profile real-user
|
||||
|
||||
# Mantener sesión larga (más orgánico)
|
||||
./navegar -url https://ejemplo.com -duration 60 -profile organic-session
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📝 Logs y Debugging
|
||||
|
||||
Cada binario genera logs:
|
||||
|
||||
```bash
|
||||
# buscar y navegar generan logs automáticos
|
||||
./navegar -url https://example.com -profile test1
|
||||
# Crea: recording_test1.log
|
||||
|
||||
# Ver log
|
||||
cat recording_test1.log
|
||||
```
|
||||
|
||||
Formato del log:
|
||||
```json
|
||||
{"timestamp":"...","type":"Navigate","params":{"url":"..."}}
|
||||
# 22:49:11 - Navigate: https://example.com
|
||||
|
||||
{"timestamp":"...","type":"Click","params":{"selector":"button"}}
|
||||
# 22:49:12 - Click: button
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Performance
|
||||
|
||||
**Headless vs Visible:**
|
||||
- Headless: Más rápido, menos memoria
|
||||
- Visible: Más sigiloso, debugging más fácil
|
||||
|
||||
**Perfiles:**
|
||||
- Primer uso: ~2-3 segundos (crea perfil)
|
||||
- Usos siguientes: ~1 segundo (reutiliza)
|
||||
|
||||
**Limitar perfiles:**
|
||||
```bash
|
||||
# Limpiar perfiles viejos
|
||||
rm -rf perfiles/temp-*
|
||||
rm -rf perfiles/bot-old-*
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 💡 Tips
|
||||
|
||||
1. **Nombres descriptivos de perfiles:**
|
||||
```bash
|
||||
./buscar -q "query" -profile "research-$(date +%Y%m%d)"
|
||||
```
|
||||
|
||||
2. **Rotación automática:**
|
||||
```bash
|
||||
PROFILE="user-$RANDOM"
|
||||
./screenshot -url https://example.com -profile "$PROFILE"
|
||||
```
|
||||
|
||||
3. **Perfiles temporales:**
|
||||
```bash
|
||||
./navegar -url https://test.com -profile "temp-$$"
|
||||
rm -rf perfiles/temp-* # Limpiar después
|
||||
```
|
||||
|
||||
4. **Compartir perfil entre binarios:**
|
||||
```bash
|
||||
# Misma sesión, diferentes tools
|
||||
./navegar -url https://github.com -profile dev-session
|
||||
./screenshot -url https://github.com/trending -profile dev-session
|
||||
# Ambos comparten las mismas cookies!
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Compilar Todos
|
||||
|
||||
```bash
|
||||
# Compilar todos los binarios
|
||||
go build -o screenshot cmd/screenshot.go
|
||||
go build -o buscar cmd/buscar.go
|
||||
go build -o navegar cmd/navegar.go
|
||||
|
||||
# O con un script
|
||||
for cmd in cmd/*.go; do
|
||||
name=$(basename "$cmd" .go)
|
||||
go build -o "$name" "$cmd"
|
||||
echo "✅ $name compilado"
|
||||
done
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📚 Crear Tus Propios Binarios
|
||||
|
||||
Usa el patrón de `cmd/*.go`:
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"navegator/pkg/browser"
|
||||
)
|
||||
|
||||
func main() {
|
||||
url := flag.String("url", "", "URL")
|
||||
profile := flag.String("profile", "mi-bot", "Perfil")
|
||||
flag.Parse()
|
||||
|
||||
config := browser.DefaultConfig()
|
||||
config.ProfileName = *profile
|
||||
// ... tu lógica
|
||||
}
|
||||
```
|
||||
|
||||
Ventajas:
|
||||
- ✅ Cada binario es independiente
|
||||
- ✅ Fácil de distribuir
|
||||
- ✅ Parámetros CLI estándar
|
||||
- ✅ Perfiles automáticos
|
||||
+199
@@ -0,0 +1,199 @@
|
||||
# Navegator - Índice de Documentación
|
||||
|
||||
Guía completa de toda la documentación disponible.
|
||||
|
||||
---
|
||||
|
||||
## 📚 Documentación Principal
|
||||
|
||||
### [README.md](../README.md)
|
||||
Introducción al proyecto, instalación rápida y uso básico.
|
||||
|
||||
**Cuándo leer:** Siempre al iniciar con el proyecto.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Guías de Uso
|
||||
|
||||
### [BINARIOS.md](BINARIOS.md)
|
||||
Guía completa de los binarios CLI (screenshot, buscar, navegar).
|
||||
|
||||
**Temas:**
|
||||
- Compilar binarios
|
||||
- Parámetros de cada binario
|
||||
- Ejemplos de uso
|
||||
- Integración con Python
|
||||
- Casos de uso reales
|
||||
|
||||
**Cuándo leer:** Para usar los binarios standalone.
|
||||
|
||||
### [PERFILES_AVANZADO.md](PERFILES_AVANZADO.md)
|
||||
Gestión avanzada de perfiles de navegador.
|
||||
|
||||
**Temas:**
|
||||
- Compartir perfiles entre proyectos
|
||||
- Usar mismo perfil en paralelo (clonación)
|
||||
- Perfiles persistentes vs temporales
|
||||
- Sincronización entre máquinas
|
||||
- Casos de uso: scraping multi-cuenta, A/B testing
|
||||
|
||||
**Cuándo leer:** Cuando necesites:
|
||||
- Mover binarios a otro repo
|
||||
- Ejecutar múltiples instancias simultáneas
|
||||
- Simular usuarios diferentes
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Guías Técnicas
|
||||
|
||||
### [STEALTH_FLAGS.md](STEALTH_FLAGS.md)
|
||||
Documentación completa de flags de Chrome para anti-detección.
|
||||
|
||||
**Temas:**
|
||||
- Flags críticas (SIEMPRE activadas)
|
||||
- Flags opcionales por contexto
|
||||
- JavaScript anti-detección
|
||||
- Configuración recomendada
|
||||
- Referencias y recursos
|
||||
|
||||
**Cuándo leer:** Para entender o personalizar las flags stealth.
|
||||
|
||||
### [TESTING.md](TESTING.md)
|
||||
Sistema completo de testing E2E y unitario.
|
||||
|
||||
**Temas:**
|
||||
- Tests unitarios (Go)
|
||||
- Tests E2E (binarios)
|
||||
- Tests de integración
|
||||
- CI/CD automático
|
||||
- Debugging tests fallidos
|
||||
- Escribir nuevos tests
|
||||
|
||||
**Cuándo leer:** Para verificar que los binarios funcionan correctamente.
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Quick Start por Caso de Uso
|
||||
|
||||
### Quiero automatizar capturas de pantalla
|
||||
1. Leer: [BINARIOS.md](BINARIOS.md) → Sección "screenshot"
|
||||
2. Compilar: `make build`
|
||||
3. Usar: `./bin/screenshot -url https://example.com -o captura.png`
|
||||
|
||||
### Quiero hacer web scraping con múltiples cuentas
|
||||
1. Leer: [PERFILES_AVANZADO.md](PERFILES_AVANZADO.md) → "Scraping Multi-Cuenta"
|
||||
2. Usar: `scripts/clonar_perfil.sh` para duplicar perfiles
|
||||
3. Ejecutar en paralelo con perfiles diferentes
|
||||
|
||||
### Quiero integrar con Python/otros lenguajes
|
||||
1. Leer: [BINARIOS.md](BINARIOS.md) → "Integración con Python"
|
||||
2. Compilar binarios: `make build`
|
||||
3. Llamar desde subprocess
|
||||
|
||||
### Quiero evitar detección de bots
|
||||
1. Leer: [STEALTH_FLAGS.md](STEALTH_FLAGS.md)
|
||||
2. Revisar flags activas por defecto
|
||||
3. Personalizar según necesidad en `pkg/stealth/flags.go`
|
||||
|
||||
### Quiero testear cambios antes de deploy
|
||||
1. Leer: [TESTING.md](TESTING.md)
|
||||
2. Ejecutar: `make test`
|
||||
3. Verificar que pasa antes de commit
|
||||
|
||||
---
|
||||
|
||||
## 📖 Orden de Lectura Recomendado
|
||||
|
||||
### Principiante
|
||||
1. README.md (introducción)
|
||||
2. BINARIOS.md (usar binarios)
|
||||
3. PERFILES_AVANZADO.md (entender perfiles)
|
||||
|
||||
### Intermedio
|
||||
4. STEALTH_FLAGS.md (personalizar detección)
|
||||
5. TESTING.md (verificar funcionamiento)
|
||||
|
||||
### Avanzado
|
||||
6. Código fuente en `pkg/` (extender funcionalidad)
|
||||
7. Scripts en `scripts/` (automatizar tareas)
|
||||
|
||||
---
|
||||
|
||||
## 🔍 Buscar por Tema
|
||||
|
||||
### Perfiles
|
||||
- Crear perfil: [BINARIOS.md](BINARIOS.md#perfiles-personalizados)
|
||||
- Compartir entre proyectos: [PERFILES_AVANZADO.md](PERFILES_AVANZADO.md#problema-1-mover-binarios)
|
||||
- Usar en paralelo: [PERFILES_AVANZADO.md](PERFILES_AVANZADO.md#problema-2-mismo-perfil-en-paralelo)
|
||||
|
||||
### Testing
|
||||
- Ejecutar tests: [TESTING.md](TESTING.md#quick-start)
|
||||
- Tests unitarios: [TESTING.md](TESTING.md#tests-unitarios-detallados)
|
||||
- Tests E2E: [TESTING.md](TESTING.md#tests-e2e-detallados)
|
||||
- CI/CD: [TESTING.md](TESTING.md#cicd-automático)
|
||||
|
||||
### Stealth
|
||||
- Flags básicas: [STEALTH_FLAGS.md](STEALTH_FLAGS.md#flags-críticas)
|
||||
- JavaScript anti-detección: [STEALTH_FLAGS.md](STEALTH_FLAGS.md#javascript-injection-anti-detección)
|
||||
- Configuración por contexto: [STEALTH_FLAGS.md](STEALTH_FLAGS.md#flags-para-contextos-específicos)
|
||||
|
||||
### Binarios
|
||||
- Compilar: [BINARIOS.md](BINARIOS.md#compilar-todos)
|
||||
- screenshot: [BINARIOS.md](BINARIOS.md#1-screenshot)
|
||||
- buscar: [BINARIOS.md](BINARIOS.md#2-buscar)
|
||||
- navegar: [BINARIOS.md](BINARIOS.md#3-navegar)
|
||||
|
||||
---
|
||||
|
||||
## 🆘 Troubleshooting
|
||||
|
||||
### Chrome no se inicia
|
||||
Ver: [TESTING.md](TESTING.md#chrome-crashed-o-cant-find-chrome)
|
||||
|
||||
### Tests fallan
|
||||
Ver: [TESTING.md](TESTING.md#debugging-tests-fallidos)
|
||||
|
||||
### Perfil bloqueado
|
||||
Ver: [PERFILES_AVANZADO.md](PERFILES_AVANZADO.md#-no-funciona-directamente)
|
||||
|
||||
### Binario no encuentra perfiles
|
||||
Ver: [PERFILES_AVANZADO.md](PERFILES_AVANZADO.md#-problema)
|
||||
|
||||
---
|
||||
|
||||
## 📝 Contribuir
|
||||
|
||||
Si encuentras errores o quieres mejorar la documentación:
|
||||
|
||||
1. Documentación está en `docs/`
|
||||
2. Ejemplos están en `examples/`
|
||||
3. Tests están en `e2e/`
|
||||
|
||||
---
|
||||
|
||||
## 🔗 Enlaces Útiles
|
||||
|
||||
- **Chrome DevTools Protocol**: https://chromedevtools.github.io/devtools-protocol/
|
||||
- **Chrome Flags**: https://peter.sh/experiments/chromium-command-line-switches/
|
||||
- **Go Testing**: https://go.dev/doc/tutorial/add-a-test
|
||||
|
||||
---
|
||||
|
||||
## ✅ Checklist Rápido
|
||||
|
||||
Antes de usar Navegator:
|
||||
- [ ] Leer README.md
|
||||
- [ ] Instalar Chrome/Chromium
|
||||
- [ ] Compilar binarios: `make build`
|
||||
- [ ] Ejecutar tests: `make test-quick`
|
||||
|
||||
Antes de usar en producción:
|
||||
- [ ] Leer STEALTH_FLAGS.md
|
||||
- [ ] Configurar perfiles persistentes
|
||||
- [ ] Ejecutar `make test`
|
||||
- [ ] Verificar en bot detection sites
|
||||
|
||||
Antes de hacer commit:
|
||||
- [ ] `make fmt`
|
||||
- [ ] `make lint`
|
||||
- [ ] `make test`
|
||||
@@ -0,0 +1,498 @@
|
||||
# Gestión Avanzada de Perfiles
|
||||
|
||||
Guía completa para mover binarios entre proyectos y usar perfiles en paralelo.
|
||||
|
||||
---
|
||||
|
||||
## 🗂️ Problema 1: Mover Binarios a Otro Repo
|
||||
|
||||
### ❌ Problema
|
||||
|
||||
```bash
|
||||
proyecto1/
|
||||
├── buscar
|
||||
└── perfiles/
|
||||
└── mi-usuario/
|
||||
└── cookies.db
|
||||
|
||||
# Copias binario a proyecto2
|
||||
proyecto2/
|
||||
├── buscar # ❌ Busca perfiles en ./perfiles/ (no existe)
|
||||
```
|
||||
|
||||
### ✅ Soluciones
|
||||
|
||||
#### **Opción A: Usar carpeta compartida en HOME** (RECOMENDADA)
|
||||
|
||||
**Ventajas:**
|
||||
- ✅ Perfiles accesibles desde cualquier proyecto
|
||||
- ✅ No duplicar datos
|
||||
- ✅ Mantiene cookies entre proyectos
|
||||
|
||||
**Ubicación por defecto:**
|
||||
```
|
||||
~/.navegator/profiles/
|
||||
├── usuario1/
|
||||
├── bot-research/
|
||||
└── dev-session/
|
||||
```
|
||||
|
||||
**Uso:**
|
||||
```bash
|
||||
# En cualquier proyecto, funciona automáticamente
|
||||
cd ~/proyecto1
|
||||
./buscar -q "golang" -profile usuario1
|
||||
|
||||
cd ~/proyecto2
|
||||
./buscar -q "python" -profile usuario1
|
||||
# ↑ Usa el MISMO perfil con cookies compartidas
|
||||
```
|
||||
|
||||
**Si compilaste con la nueva versión (`buscar_v2.go`):**
|
||||
```bash
|
||||
go build -o buscar cmd/buscar_v2.go
|
||||
|
||||
# Default: ~/.navegator/profiles
|
||||
./buscar -q "golang" -profile mi-usuario
|
||||
|
||||
# Custom: especificar ruta
|
||||
./buscar -q "golang" -profile mi-usuario -profiles-dir /ruta/custom
|
||||
```
|
||||
|
||||
#### **Opción B: Variable de entorno**
|
||||
|
||||
Agregar a `.bashrc` o `.zshrc`:
|
||||
|
||||
```bash
|
||||
export NAVEGATOR_PROFILES="$HOME/shared-profiles"
|
||||
```
|
||||
|
||||
Modificar binarios para leer:
|
||||
```go
|
||||
profilesDir := os.Getenv("NAVEGATOR_PROFILES")
|
||||
if profilesDir == "" {
|
||||
profilesDir = filepath.Join(homeDir, ".navegator", "profiles")
|
||||
}
|
||||
```
|
||||
|
||||
#### **Opción C: Copiar carpeta de perfiles**
|
||||
|
||||
```bash
|
||||
# Copiar perfiles entre proyectos
|
||||
cp -r ~/proyecto1/perfiles ~/proyecto2/
|
||||
|
||||
# Sincronizar cambios
|
||||
rsync -av ~/proyecto1/perfiles/ ~/proyecto2/perfiles/
|
||||
```
|
||||
|
||||
#### **Opción D: Symlink**
|
||||
|
||||
```bash
|
||||
# Crear carpeta compartida
|
||||
mkdir -p ~/shared-navegator-profiles
|
||||
|
||||
# En cada proyecto
|
||||
cd ~/proyecto1
|
||||
ln -s ~/shared-navegator-profiles perfiles
|
||||
|
||||
cd ~/proyecto2
|
||||
ln -s ~/shared-navegator-profiles perfiles
|
||||
|
||||
# Ambos apuntan al mismo directorio físico
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔀 Problema 2: Mismo Perfil en Paralelo
|
||||
|
||||
### ❌ No Funciona Directamente
|
||||
|
||||
Chrome bloquea múltiples instancias del mismo perfil:
|
||||
|
||||
```bash
|
||||
# Terminal 1
|
||||
./buscar -q "golang" -profile usuario1 # ✅ OK
|
||||
|
||||
# Terminal 2 (simultáneamente)
|
||||
./buscar -q "python" -profile usuario1 # ❌ ERROR
|
||||
# Chrome error: Profile is already in use
|
||||
```
|
||||
|
||||
**Archivos de lock:**
|
||||
```
|
||||
perfiles/usuario1/
|
||||
├── SingletonLock # Bloquea acceso múltiple
|
||||
├── SingletonSocket # Socket de comunicación
|
||||
└── SingletonCookie # Cookie de instancia
|
||||
```
|
||||
|
||||
### ✅ Soluciones
|
||||
|
||||
#### **Solución 1: Clonar perfiles antes de usar** (RECOMENDADA)
|
||||
|
||||
**Script automático:**
|
||||
```bash
|
||||
./scripts/clonar_perfil.sh usuario-base usuario-clon-1
|
||||
./scripts/clonar_perfil.sh usuario-base usuario-clon-2
|
||||
./scripts/clonar_perfil.sh usuario-base usuario-clon-3
|
||||
|
||||
# Ahora usar en paralelo
|
||||
./buscar -q "query1" -profile usuario-clon-1 &
|
||||
./buscar -q "query2" -profile usuario-clon-2 &
|
||||
./buscar -q "query3" -profile usuario-clon-3 &
|
||||
wait
|
||||
```
|
||||
|
||||
**¿Qué hace el script?**
|
||||
1. Copia el perfil completo (cookies, cache, historial)
|
||||
2. Elimina archivos de lock
|
||||
3. Crea perfil independiente listo para usar
|
||||
|
||||
**Ejemplo completo:**
|
||||
```bash
|
||||
# 1. Crear perfil base con login/cookies
|
||||
./navegar -url https://github.com -profile github-base
|
||||
# ... hacer login manualmente ...
|
||||
|
||||
# 2. Clonar para uso paralelo
|
||||
for i in {1..5}; do
|
||||
./scripts/clonar_perfil.sh github-base github-worker-$i
|
||||
done
|
||||
|
||||
# 3. Usar en paralelo (todos con la misma sesión)
|
||||
for i in {1..5}; do
|
||||
./buscar -q "topic-$i" -profile github-worker-$i &
|
||||
done
|
||||
wait
|
||||
```
|
||||
|
||||
#### **Solución 2: Usar perfiles diferentes**
|
||||
|
||||
Diseñar desde el inicio con múltiples perfiles:
|
||||
|
||||
```bash
|
||||
# Crear perfiles específicos
|
||||
./navegar -url https://app.com -profile worker-1
|
||||
./navegar -url https://app.com -profile worker-2
|
||||
./navegar -url https://app.com -profile worker-3
|
||||
|
||||
# Usar en paralelo
|
||||
./buscar -q "query1" -profile worker-1 &
|
||||
./buscar -q "query2" -profile worker-2 &
|
||||
./buscar -q "query3" -profile worker-3 &
|
||||
```
|
||||
|
||||
#### **Solución 3: Pool de perfiles rotativos**
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# pool_buscar.sh
|
||||
|
||||
PROFILES=("bot-1" "bot-2" "bot-3" "bot-4" "bot-5")
|
||||
QUERIES=("golang" "python" "rust" "javascript" "java")
|
||||
|
||||
for i in "${!QUERIES[@]}"; do
|
||||
PROFILE="${PROFILES[$i]}"
|
||||
QUERY="${QUERIES[$i]}"
|
||||
|
||||
echo "🔍 Buscando '$QUERY' con perfil $PROFILE"
|
||||
./buscar -q "$QUERY" -profile "$PROFILE" -output "result_$i.json" &
|
||||
done
|
||||
|
||||
wait
|
||||
echo "✅ Todas las búsquedas completadas"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 Casos de Uso Reales
|
||||
|
||||
### **Caso 1: Scraping Multi-Cuenta**
|
||||
|
||||
Necesitas hacer scraping con 10 cuentas diferentes simultáneamente.
|
||||
|
||||
```bash
|
||||
# Preparación (una vez)
|
||||
for i in {1..10}; do
|
||||
./navegar -url https://sitio.com/login \
|
||||
-profile account-$i \
|
||||
-type "#username" -text "user$i" \
|
||||
-duration 5
|
||||
# Hacer login manualmente si es necesario
|
||||
done
|
||||
|
||||
# Uso (todas a la vez)
|
||||
for i in {1..10}; do
|
||||
./navegar -url https://sitio.com/dashboard \
|
||||
-profile account-$i \
|
||||
-duration 10 &
|
||||
done
|
||||
wait
|
||||
```
|
||||
|
||||
### **Caso 2: A/B Testing con Misma Sesión**
|
||||
|
||||
Probar variantes con cookies idénticas:
|
||||
|
||||
```bash
|
||||
# Crear perfil base
|
||||
./navegar -url https://app.com -profile base-session
|
||||
# ... configurar cookies/preferencias ...
|
||||
|
||||
# Clonar para cada variante
|
||||
./scripts/clonar_perfil.sh base-session variant-a
|
||||
./scripts/clonar_perfil.sh base-session variant-b
|
||||
|
||||
# Probar en paralelo
|
||||
./screenshot -url https://app.com?variant=a -profile variant-a -o test-a.png &
|
||||
./screenshot -url https://app.com?variant=b -profile variant-b -o test-b.png &
|
||||
wait
|
||||
|
||||
# Comparar resultados
|
||||
compare test-a.png test-b.png diff.png
|
||||
```
|
||||
|
||||
### **Caso 3: Búsqueda Distribuida**
|
||||
|
||||
Buscar múltiples keywords sin rate limiting:
|
||||
|
||||
```bash
|
||||
# Crear pool de 20 perfiles
|
||||
for i in {1..20}; do
|
||||
./scripts/clonar_perfil.sh base-search search-worker-$i
|
||||
done
|
||||
|
||||
# Buscar 100 keywords en paralelo (lotes de 20)
|
||||
keywords=("keyword1" "keyword2" ... "keyword100")
|
||||
|
||||
for i in "${!keywords[@]}"; do
|
||||
profile_idx=$((i % 20 + 1))
|
||||
./buscar -q "${keywords[$i]}" \
|
||||
-profile "search-worker-$profile_idx" \
|
||||
-output "result_$i.json" &
|
||||
|
||||
# Cada 20 búsquedas, esperar
|
||||
if [ $((i % 20)) -eq 19 ]; then
|
||||
wait
|
||||
fi
|
||||
done
|
||||
```
|
||||
|
||||
### **Caso 4: Proyectos Diferentes, Mismo Perfil**
|
||||
|
||||
```bash
|
||||
# Proyecto 1: Análisis de datos
|
||||
cd ~/proyecto-scraper
|
||||
./buscar -q "data science" -profile researcher-123
|
||||
|
||||
# Proyecto 2: Generación de reportes
|
||||
cd ~/proyecto-reportes
|
||||
./screenshot -url https://dashboard.com -profile researcher-123
|
||||
# ↑ Usa las mismas cookies del perfil!
|
||||
|
||||
# Proyecto 3: Monitoreo
|
||||
cd ~/proyecto-monitor
|
||||
./navegar -url https://app.com/status -profile researcher-123
|
||||
```
|
||||
|
||||
**Resultado:** El perfil `researcher-123` se comparte entre los 3 proyectos sin duplicar datos.
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ Herramientas Útiles
|
||||
|
||||
### **Ver perfiles activos**
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# ver_perfiles_activos.sh
|
||||
|
||||
echo "🔍 Perfiles actualmente en uso:"
|
||||
echo ""
|
||||
|
||||
PROFILES_DIR="$HOME/.navegator/profiles"
|
||||
|
||||
for profile in "$PROFILES_DIR"/*; do
|
||||
if [ -d "$profile" ]; then
|
||||
name=$(basename "$profile")
|
||||
|
||||
if [ -f "$profile/SingletonLock" ]; then
|
||||
pid=$(cat "$profile/SingletonLock" 2>/dev/null | grep -oP '\d+')
|
||||
echo "🟢 $name (PID: $pid)"
|
||||
else
|
||||
echo "⚪ $name (libre)"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
```
|
||||
|
||||
### **Limpiar perfiles no usados**
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# limpiar_perfiles_viejos.sh
|
||||
|
||||
PROFILES_DIR="$HOME/.navegator/profiles"
|
||||
DAYS=30
|
||||
|
||||
echo "🗑️ Eliminando perfiles sin usar en $DAYS días..."
|
||||
|
||||
find "$PROFILES_DIR" -maxdepth 1 -type d -mtime +$DAYS | while read profile; do
|
||||
if [ "$profile" != "$PROFILES_DIR" ]; then
|
||||
name=$(basename "$profile")
|
||||
echo " Eliminando: $name"
|
||||
rm -rf "$profile"
|
||||
fi
|
||||
done
|
||||
|
||||
echo "✅ Limpieza completada"
|
||||
```
|
||||
|
||||
### **Sincronizar perfiles entre máquinas**
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# sync_perfiles.sh
|
||||
|
||||
REMOTE_HOST="servidor.com"
|
||||
REMOTE_USER="usuario"
|
||||
LOCAL_DIR="$HOME/.navegator/profiles"
|
||||
REMOTE_DIR="/home/$REMOTE_USER/.navegator/profiles"
|
||||
|
||||
echo "📤 Subiendo perfiles al servidor..."
|
||||
rsync -avz --progress "$LOCAL_DIR/" "$REMOTE_USER@$REMOTE_HOST:$REMOTE_DIR/"
|
||||
|
||||
echo "✅ Sincronización completada"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📝 Mejores Prácticas
|
||||
|
||||
### **1. Nomenclatura de Perfiles**
|
||||
|
||||
```bash
|
||||
# ❌ Mal
|
||||
perfil1, perfil2, test, abc
|
||||
|
||||
# ✅ Bien
|
||||
github-devuser-1
|
||||
scraper-bot-2024-01
|
||||
researcher-project-alpha
|
||||
```
|
||||
|
||||
### **2. Perfiles Base + Clones**
|
||||
|
||||
```bash
|
||||
# Crear perfil base con configuración
|
||||
base-authenticated/
|
||||
|
||||
# Clonar para uso paralelo
|
||||
base-authenticated-clone-1/
|
||||
base-authenticated-clone-2/
|
||||
base-authenticated-clone-3/
|
||||
```
|
||||
|
||||
### **3. Limpieza Regular**
|
||||
|
||||
```bash
|
||||
# Eliminar clones temporales después de usar
|
||||
rm -rf perfiles/*-clone-*
|
||||
rm -rf perfiles/temp-*
|
||||
|
||||
# Mantener solo perfiles base
|
||||
```
|
||||
|
||||
### **4. Backup de Perfiles Importantes**
|
||||
|
||||
```bash
|
||||
# Backup
|
||||
tar -czf perfiles-backup-$(date +%Y%m%d).tar.gz perfiles/
|
||||
|
||||
# Restaurar
|
||||
tar -xzf perfiles-backup-20260324.tar.gz
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ⚡ Performance
|
||||
|
||||
### **Perfiles ligeros vs pesados**
|
||||
|
||||
```bash
|
||||
# Perfil nuevo (primera vez): 2-3 segundos
|
||||
./buscar -q "query" -profile nuevo-perfil
|
||||
|
||||
# Perfil existente: 1 segundo
|
||||
./buscar -q "query" -profile perfil-usado
|
||||
|
||||
# Perfil con mucho cache: 1-2 segundos
|
||||
```
|
||||
|
||||
### **Límites prácticos**
|
||||
|
||||
- ✅ **5-10 perfiles en paralelo**: Funciona bien
|
||||
- ⚠️ **20-30 perfiles en paralelo**: Depende del CPU/RAM
|
||||
- ❌ **50+ perfiles en paralelo**: Puede saturar sistema
|
||||
|
||||
### **Optimización**
|
||||
|
||||
```bash
|
||||
# Ejecutar en lotes
|
||||
for i in {1..100}; do
|
||||
./buscar -q "query$i" -profile "bot-$((i % 10))" &
|
||||
|
||||
# Cada 10, esperar
|
||||
if [ $((i % 10)) -eq 9 ]; then
|
||||
wait
|
||||
fi
|
||||
done
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔒 Seguridad
|
||||
|
||||
### **Perfiles sensibles**
|
||||
|
||||
Si tus perfiles tienen sesiones autenticadas:
|
||||
|
||||
```bash
|
||||
# Proteger perfiles
|
||||
chmod 700 ~/.navegator/profiles/
|
||||
chmod 600 ~/.navegator/profiles/*/cookies*
|
||||
|
||||
# Encriptar backup
|
||||
tar -czf - perfiles/ | gpg -c > perfiles-encrypted.tar.gz.gpg
|
||||
```
|
||||
|
||||
### **No compartir perfiles con credenciales**
|
||||
|
||||
```bash
|
||||
# ❌ NO hacer
|
||||
git add perfiles/
|
||||
git commit -m "Added profiles" # Expondrías cookies/tokens
|
||||
|
||||
# ✅ Hacer
|
||||
echo "perfiles/" >> .gitignore
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📚 Resumen
|
||||
|
||||
| Escenario | Solución |
|
||||
|-----------|----------|
|
||||
| Mover binario a otro repo | Usar `~/.navegator/profiles` (compartido) |
|
||||
| Mismo perfil en paralelo | Clonar con `clonar_perfil.sh` |
|
||||
| Múltiples proyectos | Flag `-profiles-dir` o symlink |
|
||||
| Scraping masivo | Pool de perfiles + rotación |
|
||||
| A/B testing | Clonar perfil base para cada variante |
|
||||
| Sincronizar entre máquinas | `rsync` de `~/.navegator/profiles` |
|
||||
|
||||
**Comando más útil:**
|
||||
```bash
|
||||
./scripts/clonar_perfil.sh base-perfil clon-1
|
||||
```
|
||||
|
||||
Esto te permite usar el mismo perfil (cookies, sesión) en múltiples instancias simultáneas.
|
||||
@@ -0,0 +1,324 @@
|
||||
# Chrome Stealth Flags - Documentación Completa
|
||||
|
||||
Esta documentación lista todas las flags necesarias para ejecutar Chrome/Chromium con la menor detección posible de automatización.
|
||||
|
||||
## Flags Críticas (Siempre Activadas)
|
||||
|
||||
### 1. Desactivar Detección de Automatización
|
||||
|
||||
```go
|
||||
"--disable-blink-features=AutomationControlled"
|
||||
```
|
||||
**Propósito**: Elimina `navigator.webdriver = true` que es el indicador más obvio de automatización.
|
||||
**Impacto**: CRÍTICO - Sin esto, casi cualquier sitio detectará la automatización.
|
||||
|
||||
```go
|
||||
"--exclude-switches=enable-automation"
|
||||
```
|
||||
**Propósito**: Evita que Chrome agregue el flag `--enable-automation` automáticamente.
|
||||
**Impacto**: ALTO - Complementa la desactivación de AutomationControlled.
|
||||
|
||||
### 2. Gestión de Perfiles y User Data
|
||||
|
||||
```go
|
||||
"--user-data-dir=/path/to/profile"
|
||||
```
|
||||
**Propósito**: Especifica dónde Chrome almacena cookies, historial, extensiones, etc.
|
||||
**Impacto**: CRÍTICO - Permite persistencia de sesión y reutilización de perfiles.
|
||||
**Nota**: Debe ser ruta absoluta única por instancia.
|
||||
|
||||
```go
|
||||
"--profile-directory=Default"
|
||||
```
|
||||
**Propósito**: Nombre del perfil dentro de user-data-dir.
|
||||
**Impacto**: MEDIO - Permite múltiples perfiles en el mismo user-data-dir.
|
||||
|
||||
### 3. Modo Sin Interfaz Gráfica
|
||||
|
||||
```go
|
||||
"--headless=new"
|
||||
```
|
||||
**Propósito**: Ejecuta Chrome sin ventana visible (nuevo modo headless estable).
|
||||
**Impacto**: ALTO - Mejor rendimiento, pero puede ser detectado.
|
||||
**Alternativa**: Omitir para modo con interfaz visible (más sigiloso pero usa más recursos).
|
||||
|
||||
```go
|
||||
"--disable-gpu"
|
||||
```
|
||||
**Propósito**: Desactiva aceleración por GPU (necesario en algunos entornos headless).
|
||||
**Impacto**: MEDIO - Evita crashes en servidores sin GPU.
|
||||
|
||||
### 4. Configuración de Ventana
|
||||
|
||||
```go
|
||||
"--window-size=1920,1080"
|
||||
```
|
||||
**Propósito**: Define tamaño de viewport.
|
||||
**Impacto**: MEDIO - Sitios pueden detectar tamaños anormales.
|
||||
**Recomendación**: Usar resoluciones comunes (1920x1080, 1366x768, 1440x900).
|
||||
|
||||
```go
|
||||
"--start-maximized"
|
||||
```
|
||||
**Propósito**: Inicia ventana maximizada (solo modo no-headless).
|
||||
**Impacto**: BAJO - Apariencia más natural en modo visible.
|
||||
|
||||
## Flags de Evasión Avanzada
|
||||
|
||||
### 5. User Agent y Detección de Plataforma
|
||||
|
||||
```go
|
||||
"--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36"
|
||||
```
|
||||
**Propósito**: Sobrescribe el user agent del navegador.
|
||||
**Impacto**: ALTO - Debe coincidir con la plataforma y versión de Chrome real.
|
||||
**Nota**: Actualizar según versión de Chrome instalada.
|
||||
|
||||
### 6. Permisos y Notificaciones
|
||||
|
||||
```go
|
||||
"--disable-notifications"
|
||||
```
|
||||
**Propósito**: Bloquea solicitudes de notificaciones del navegador.
|
||||
**Impacto**: BAJO - Evita interrupciones molestas.
|
||||
|
||||
```go
|
||||
"--disable-popup-blocking"
|
||||
```
|
||||
**Propósito**: Permite abrir popups sin bloqueo.
|
||||
**Impacto**: BAJO - Útil para algunos flujos de autenticación.
|
||||
|
||||
### 7. Seguridad y Privacidad
|
||||
|
||||
```go
|
||||
"--disable-web-security"
|
||||
```
|
||||
**Propósito**: Desactiva CORS y otras políticas de seguridad.
|
||||
**Impacto**: MEDIO - Útil para testing, pero inseguro.
|
||||
**⚠️ COMENTAR POR DEFECTO** - Solo activar si es necesario.
|
||||
|
||||
```go
|
||||
"--disable-features=IsolateOrigins,site-per-process"
|
||||
```
|
||||
**Propósito**: Desactiva aislamiento de procesos por sitio.
|
||||
**Impacto**: BAJO - Reduce consumo de memoria.
|
||||
**⚠️ COMENTAR POR DEFECTO** - Puede afectar estabilidad.
|
||||
|
||||
```go
|
||||
"--disable-site-isolation-trials"
|
||||
```
|
||||
**Propósito**: Desactiva experimentos de aislamiento de sitios.
|
||||
**Impacto**: BAJO - Complementa flags anteriores.
|
||||
|
||||
### 8. Optimización de Rendimiento
|
||||
|
||||
```go
|
||||
"--disable-dev-shm-usage"
|
||||
```
|
||||
**Propósito**: Evita uso de /dev/shm en Docker/containers.
|
||||
**Impacto**: MEDIO - Crítico en entornos containerizados.
|
||||
|
||||
```go
|
||||
"--no-sandbox"
|
||||
```
|
||||
**Propósito**: Desactiva sandbox de Chrome.
|
||||
**Impacto**: ALTO - **PELIGROSO** - Solo usar en entornos confiables (Docker, VMs).
|
||||
**⚠️ COMENTAR POR DEFECTO** - Riesgo de seguridad.
|
||||
|
||||
```go
|
||||
"--disable-setuid-sandbox"
|
||||
```
|
||||
**Propósito**: Desactiva sandbox SUID.
|
||||
**Impacto**: MEDIO - Similar a --no-sandbox.
|
||||
**⚠️ COMENTAR POR DEFECTO** - Usar solo si --no-sandbox está activo.
|
||||
|
||||
### 9. Extensions y Plugins
|
||||
|
||||
```go
|
||||
"--disable-extensions"
|
||||
```
|
||||
**Propósito**: Desactiva todas las extensiones de Chrome.
|
||||
**Impacto**: BAJO - Reduce superficie de detección.
|
||||
|
||||
```go
|
||||
"--disable-plugins"
|
||||
```
|
||||
**Propósito**: Desactiva plugins (Flash, PDF viewer, etc).
|
||||
**Impacto**: BAJO - Mejora rendimiento.
|
||||
|
||||
### 10. Logs y Debugging
|
||||
|
||||
```go
|
||||
"--enable-logging"
|
||||
```
|
||||
**Propósito**: Activa logs de Chrome.
|
||||
**Impacto**: BAJO - Útil para debugging.
|
||||
**⚠️ COMENTAR EN PRODUCCIÓN**
|
||||
|
||||
```go
|
||||
"--v=1"
|
||||
```
|
||||
**Propósito**: Nivel de verbosidad de logs (0-3).
|
||||
**Impacto**: BAJO - Combinar con --enable-logging.
|
||||
|
||||
```go
|
||||
"--log-level=0"
|
||||
```
|
||||
**Propósito**: Nivel de log (0=INFO, 1=WARNING, 2=ERROR).
|
||||
**Impacto**: BAJO - Control fino de logs.
|
||||
|
||||
### 11. Características Especiales
|
||||
|
||||
```go
|
||||
"--disable-background-timer-throttling"
|
||||
```
|
||||
**Propósito**: Evita throttling de timers en background.
|
||||
**Impacto**: BAJO - Útil para scrapers que esperan en background.
|
||||
|
||||
```go
|
||||
"--disable-backgrounding-occluded-windows"
|
||||
```
|
||||
**Propósito**: Evita suspensión de ventanas ocultas.
|
||||
**Impacto**: BAJO - Mantiene páginas activas aunque no sean visibles.
|
||||
|
||||
```go
|
||||
"--disable-renderer-backgrounding"
|
||||
```
|
||||
**Propósito**: Evita que el renderer entre en modo background.
|
||||
**Impacto**: BAJO - Mejora consistencia en ejecución.
|
||||
|
||||
```go
|
||||
"--disable-ipc-flooding-protection"
|
||||
```
|
||||
**Propósito**: Desactiva protección contra flooding de IPC.
|
||||
**Impacto**: BAJO - Útil cuando se envían muchos comandos CDP rápidamente.
|
||||
|
||||
### 12. Features de Chrome a Desactivar
|
||||
|
||||
```go
|
||||
"--disable-features=TranslateUI"
|
||||
```
|
||||
**Propósito**: Desactiva ofertas de traducción automática.
|
||||
**Impacto**: BAJO - Menos interrupciones.
|
||||
|
||||
```go
|
||||
"--disable-features=PrivacySandboxSettings4"
|
||||
```
|
||||
**Propósito**: Desactiva configuración de Privacy Sandbox.
|
||||
**Impacto**: BAJO - Reduce telemetría.
|
||||
|
||||
## Flags para Contextos Específicos
|
||||
|
||||
### Docker/Containers
|
||||
```go
|
||||
"--no-sandbox"
|
||||
"--disable-setuid-sandbox"
|
||||
"--disable-dev-shm-usage"
|
||||
```
|
||||
|
||||
### Headless Máximo Sigilo
|
||||
```go
|
||||
"--headless=new"
|
||||
"--disable-gpu"
|
||||
"--hide-scrollbars"
|
||||
"--mute-audio"
|
||||
```
|
||||
|
||||
### Debugging
|
||||
```go
|
||||
"--enable-logging"
|
||||
"--v=1"
|
||||
"--remote-debugging-port=0" // Puerto aleatorio, CDP asignará uno
|
||||
```
|
||||
|
||||
## Configuración Recomendada por Defecto
|
||||
|
||||
```go
|
||||
var DefaultStealthFlags = []string{
|
||||
// CRÍTICAS - Siempre activadas
|
||||
"--disable-blink-features=AutomationControlled",
|
||||
"--exclude-switches=enable-automation",
|
||||
|
||||
// Headless moderno
|
||||
"--headless=new",
|
||||
"--disable-gpu",
|
||||
|
||||
// Ventana
|
||||
"--window-size=1920,1080",
|
||||
|
||||
// Optimización
|
||||
"--disable-dev-shm-usage",
|
||||
"--disable-extensions",
|
||||
|
||||
// Estabilidad
|
||||
"--disable-background-timer-throttling",
|
||||
"--disable-backgrounding-occluded-windows",
|
||||
"--disable-renderer-backgrounding",
|
||||
|
||||
// Menos ruido
|
||||
"--disable-notifications",
|
||||
"--disable-features=TranslateUI",
|
||||
|
||||
// COMENTADAS - Activar según necesidad:
|
||||
// "--no-sandbox", // Solo Docker/confiable
|
||||
// "--disable-web-security", // Solo para testing
|
||||
// "--enable-logging", // Solo debugging
|
||||
}
|
||||
```
|
||||
|
||||
## JavaScript Injection Anti-Detección
|
||||
|
||||
Además de las flags, inyectar este script en cada página:
|
||||
|
||||
```javascript
|
||||
// Sobrescribir propiedades que delatan automatización
|
||||
Object.defineProperty(navigator, 'webdriver', {
|
||||
get: () => undefined
|
||||
});
|
||||
|
||||
// Eliminar _selenium, _webdriver, callSelenium
|
||||
delete window.navigator.__proto__.webdriver;
|
||||
|
||||
// Chrome runtime mock
|
||||
window.chrome = {
|
||||
runtime: {},
|
||||
loadTimes: function() {},
|
||||
csi: function() {},
|
||||
app: {}
|
||||
};
|
||||
|
||||
// Permisos mock
|
||||
const originalQuery = window.navigator.permissions.query;
|
||||
window.navigator.permissions.query = (parameters) => (
|
||||
parameters.name === 'notifications' ?
|
||||
Promise.resolve({ state: Notification.permission }) :
|
||||
originalQuery(parameters)
|
||||
);
|
||||
|
||||
// Plugin array fix
|
||||
Object.defineProperty(navigator, 'plugins', {
|
||||
get: () => [1, 2, 3, 4, 5]
|
||||
});
|
||||
|
||||
// Languages fix
|
||||
Object.defineProperty(navigator, 'languages', {
|
||||
get: () => ['en-US', 'en']
|
||||
});
|
||||
```
|
||||
|
||||
## Orden de Prioridad
|
||||
|
||||
1. **CRÍTICO**: `--disable-blink-features=AutomationControlled`
|
||||
2. **CRÍTICO**: `--exclude-switches=enable-automation`
|
||||
3. **CRÍTICO**: `--user-data-dir` (perfiles persistentes)
|
||||
4. **ALTO**: `--headless=new` (o omitir para modo visible)
|
||||
5. **ALTO**: User-Agent correcto
|
||||
6. **MEDIO**: Window size realista
|
||||
7. **MEDIO**: JavaScript injection anti-detección
|
||||
8. **BAJO**: Resto de flags según contexto
|
||||
|
||||
## Referencias
|
||||
|
||||
- [Chrome Command Line Switches](https://peter.sh/experiments/chromium-command-line-switches/)
|
||||
- [Chrome DevTools Protocol](https://chromedevtools.github.io/devtools-protocol/)
|
||||
- [Puppeteer Extra Stealth Plugin](https://github.com/berstend/puppeteer-extra/tree/master/packages/puppeteer-extra-plugin-stealth)
|
||||
+557
@@ -0,0 +1,557 @@
|
||||
# Testing Guide - Navegator
|
||||
|
||||
Sistema completo de testing E2E para validar que los binarios funcionan correctamente.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Tipos de Tests
|
||||
|
||||
### 1. **Tests Unitarios** (Go)
|
||||
Tests de funciones individuales en Go.
|
||||
|
||||
```bash
|
||||
# Ejecutar todos los tests unitarios
|
||||
make test-unit
|
||||
|
||||
# O directamente con go test
|
||||
go test -v ./pkg/browser/...
|
||||
go test -v ./pkg/cdp/...
|
||||
go test -v ./pkg/stealth/...
|
||||
```
|
||||
|
||||
**Cobertura:**
|
||||
- ✅ Launch browser
|
||||
- ✅ Navigate
|
||||
- ✅ Screenshot
|
||||
- ✅ JavaScript evaluation
|
||||
- ✅ Stealth flags
|
||||
- ✅ Recorder
|
||||
- ✅ Profile persistence
|
||||
|
||||
### 2. **Tests E2E** (Bash)
|
||||
Tests de binarios compilados end-to-end.
|
||||
|
||||
```bash
|
||||
# Ejecutar tests E2E
|
||||
make test-e2e
|
||||
|
||||
# O directamente
|
||||
./test/e2e_test.sh
|
||||
```
|
||||
|
||||
**Cobertura:**
|
||||
- ✅ Screenshot básico y con opciones
|
||||
- ✅ Búsqueda (con timeout esperado)
|
||||
- ✅ Navegación y recording
|
||||
- ✅ Perfiles personalizados
|
||||
- ✅ Persistencia de perfiles
|
||||
- ✅ Error handling
|
||||
|
||||
### 3. **Tests de Integración** (Bash)
|
||||
Tests de integración entre componentes.
|
||||
|
||||
```bash
|
||||
# Ejecutar tests de integración
|
||||
make test-integration
|
||||
|
||||
# O directamente
|
||||
./test/integration_test.sh
|
||||
```
|
||||
|
||||
**Cobertura:**
|
||||
- ✅ Compartir perfiles entre binarios
|
||||
- ✅ Recording de múltiples acciones
|
||||
- ✅ Perfiles en paralelo (clonados)
|
||||
- ✅ Output JSON válido
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Quick Start
|
||||
|
||||
### Ejecutar todos los tests
|
||||
```bash
|
||||
make test
|
||||
```
|
||||
|
||||
### Tests rápidos (solo unitarios)
|
||||
```bash
|
||||
make test-quick
|
||||
```
|
||||
|
||||
### Solo E2E
|
||||
```bash
|
||||
make build
|
||||
make test-e2e
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 Estructura de Tests
|
||||
|
||||
```
|
||||
navegator/
|
||||
├── pkg/
|
||||
│ └── browser/
|
||||
│ └── browser_test.go # Tests unitarios
|
||||
├── test/
|
||||
│ ├── e2e_test.sh # Tests E2E de binarios
|
||||
│ └── integration_test.sh # Tests de integración
|
||||
├── Makefile # Comandos de testing
|
||||
└── .github/
|
||||
└── workflows/
|
||||
└── test.yml # CI/CD automático
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🧪 Tests Unitarios Detallados
|
||||
|
||||
### TestLaunchBrowser
|
||||
Verifica que el navegador se lance correctamente.
|
||||
|
||||
```go
|
||||
func TestLaunchBrowser(t *testing.T) {
|
||||
// Lanza Chrome con perfil temporal
|
||||
// Verifica: perfil creado, debug URL, target ID
|
||||
}
|
||||
```
|
||||
|
||||
### TestNavigate
|
||||
Verifica navegación a URLs.
|
||||
|
||||
```go
|
||||
func TestNavigate(t *testing.T) {
|
||||
// Navega a example.com
|
||||
// Verifica URL correcta via JavaScript
|
||||
}
|
||||
```
|
||||
|
||||
### TestScreenshot
|
||||
Verifica capturas de pantalla.
|
||||
|
||||
```go
|
||||
func TestScreenshot(t *testing.T) {
|
||||
// Toma screenshot
|
||||
// Verifica: PNG válido, tamaño > 0
|
||||
}
|
||||
```
|
||||
|
||||
### TestStealthFlags
|
||||
Verifica flags anti-detección.
|
||||
|
||||
```go
|
||||
func TestStealthFlags(t *testing.T) {
|
||||
// Evalúa navigator.webdriver
|
||||
// Verifica: false o undefined
|
||||
// Verifica: window.chrome existe
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Tests E2E Detallados
|
||||
|
||||
### Suite: screenshot
|
||||
|
||||
**Test 1: Captura básica**
|
||||
```bash
|
||||
./screenshot -url https://example.com -o test.png
|
||||
# Verifica: PNG válido, archivo existe
|
||||
```
|
||||
|
||||
**Test 2: Perfil personalizado**
|
||||
```bash
|
||||
./screenshot -profile custom-123 -url https://example.com
|
||||
# Verifica: perfil creado en disco
|
||||
```
|
||||
|
||||
**Test 3: Dimensiones custom**
|
||||
```bash
|
||||
./screenshot -width=800 -height=600 -url https://example.com
|
||||
# Verifica: screenshot generado
|
||||
```
|
||||
|
||||
### Suite: buscar
|
||||
|
||||
**Test 4: Búsqueda básica**
|
||||
```bash
|
||||
./buscar -q "test" -n 3 -output results.json
|
||||
# Verifica: no crash (puede tener timeout de red)
|
||||
```
|
||||
|
||||
**Test 5: Perfil personalizado**
|
||||
```bash
|
||||
./buscar -profile test-search -q "query"
|
||||
# Verifica: perfil creado
|
||||
```
|
||||
|
||||
### Suite: navegar
|
||||
|
||||
**Test 6: Navegación básica**
|
||||
```bash
|
||||
./navegar -url https://example.com -duration 2
|
||||
# Verifica: recording creado
|
||||
```
|
||||
|
||||
**Test 7: Recording funciona**
|
||||
```bash
|
||||
# Verifica contenido del recording log
|
||||
grep "Navigate" recording_*.log
|
||||
```
|
||||
|
||||
### Suite: Perfiles
|
||||
|
||||
**Test 8: Persistencia**
|
||||
```bash
|
||||
# Primera sesión: crea perfil
|
||||
./screenshot -profile persist-test -url https://example.com
|
||||
|
||||
# Segunda sesión: reutiliza
|
||||
./screenshot -profile persist-test -url https://example.com
|
||||
|
||||
# Verifica: perfil existe después de ambas
|
||||
```
|
||||
|
||||
**Test 9: Múltiples perfiles**
|
||||
```bash
|
||||
# Crear múltiples perfiles en paralelo
|
||||
./screenshot -profile multi-1 &
|
||||
./screenshot -profile multi-2 &
|
||||
wait
|
||||
|
||||
# Verifica: ambos existen
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔗 Tests de Integración Detallados
|
||||
|
||||
### Test 1: Compartir perfil entre binarios
|
||||
```bash
|
||||
# navegar crea sesión
|
||||
./navegar -url https://example.com -profile shared
|
||||
|
||||
# screenshot usa misma sesión
|
||||
./screenshot -url https://example.com -profile shared
|
||||
|
||||
# Verifica: mismo perfil usado
|
||||
```
|
||||
|
||||
### Test 2: Recording de múltiples acciones
|
||||
```bash
|
||||
./navegar -url https://example.com -duration 3
|
||||
|
||||
# Verifica: recording contiene JSON válido con acciones
|
||||
```
|
||||
|
||||
### Test 3: Perfiles clonados en paralelo
|
||||
```bash
|
||||
# Clonar perfil base
|
||||
cp -r base clone1
|
||||
cp -r base clone2
|
||||
|
||||
# Ejecutar en paralelo
|
||||
./screenshot -profile clone1 &
|
||||
./screenshot -profile clone2 &
|
||||
|
||||
# Verifica: ambos completan sin error
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📈 Cobertura de Código
|
||||
|
||||
### Generar reporte
|
||||
```bash
|
||||
make coverage
|
||||
```
|
||||
|
||||
Genera `coverage.html` con visualización de cobertura.
|
||||
|
||||
### Ver cobertura en terminal
|
||||
```bash
|
||||
go test -cover ./pkg/...
|
||||
```
|
||||
|
||||
### Cobertura por paquete
|
||||
```bash
|
||||
go test -coverprofile=coverage.out ./pkg/browser
|
||||
go tool cover -func=coverage.out
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔄 CI/CD Automático
|
||||
|
||||
### GitHub Actions
|
||||
|
||||
El workflow `.github/workflows/test.yml` ejecuta automáticamente:
|
||||
|
||||
1. **Unit Tests** - En cada push/PR
|
||||
2. **E2E Tests** - Con Chrome instalado
|
||||
3. **Integration Tests** - Verificación completa
|
||||
4. **Lint** - Análisis de código
|
||||
|
||||
### Configuración
|
||||
|
||||
```yaml
|
||||
on:
|
||||
push:
|
||||
branches: [ main, master, develop ]
|
||||
pull_request:
|
||||
branches: [ main, master ]
|
||||
```
|
||||
|
||||
### Ver resultados
|
||||
|
||||
En GitHub: **Actions** tab → Ver runs → Detalles de cada job
|
||||
|
||||
---
|
||||
|
||||
## 🐛 Debugging Tests Fallidos
|
||||
|
||||
### Test unitario falla
|
||||
|
||||
```bash
|
||||
# Ejecutar con verbose
|
||||
go test -v ./pkg/browser/ -run TestName
|
||||
|
||||
# Ver logs completos
|
||||
go test -v ./pkg/browser/ 2>&1 | tee test.log
|
||||
```
|
||||
|
||||
### Test E2E falla
|
||||
|
||||
```bash
|
||||
# Ejecutar directamente sin make
|
||||
./test/e2e_test.sh
|
||||
|
||||
# Ver archivos generados
|
||||
ls -la *.png *.json test-profiles/
|
||||
```
|
||||
|
||||
### Chrome no se inicia
|
||||
|
||||
```bash
|
||||
# Verificar Chrome instalado
|
||||
which google-chrome
|
||||
|
||||
# Probar manualmente
|
||||
google-chrome --version
|
||||
|
||||
# Ver si hay procesos colgados
|
||||
ps aux | grep chrome
|
||||
pkill -9 chrome
|
||||
```
|
||||
|
||||
### Timeout en búsquedas
|
||||
|
||||
Las búsquedas en DuckDuckGo pueden tardar. Esto es **esperado** y el test lo marca como `SKIP`.
|
||||
|
||||
```bash
|
||||
# Test marcado como SKIP por timeout de red
|
||||
# Esto NO es un fallo del binario
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎭 Tests de Regresión
|
||||
|
||||
### Crear baseline
|
||||
|
||||
```bash
|
||||
# Capturar estado actual
|
||||
make test > baseline.txt
|
||||
```
|
||||
|
||||
### Comparar con baseline
|
||||
|
||||
```bash
|
||||
# Ejecutar tests nuevamente
|
||||
make test > current.txt
|
||||
|
||||
# Comparar
|
||||
diff baseline.txt current.txt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📝 Escribir Nuevos Tests
|
||||
|
||||
### Test unitario
|
||||
|
||||
1. Crear archivo `*_test.go` en el paquete
|
||||
2. Función con prefijo `Test`
|
||||
3. Usar `t.TempDir()` para archivos temporales
|
||||
|
||||
```go
|
||||
func TestMyFeature(t *testing.T) {
|
||||
tempDir := t.TempDir()
|
||||
|
||||
// Tu código aquí
|
||||
|
||||
if resultado != esperado {
|
||||
t.Errorf("Expected %v, got %v", esperado, resultado)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Test E2E
|
||||
|
||||
Agregar a `test/e2e_test.sh`:
|
||||
|
||||
```bash
|
||||
TEST_NAME="mi-feature: descripción"
|
||||
if ./mi-binario -arg valor; then
|
||||
if [ condición ]; then
|
||||
report_test "$TEST_NAME" "PASS"
|
||||
else
|
||||
report_test "$TEST_NAME" "FAIL" "Razón"
|
||||
fi
|
||||
else
|
||||
report_test "$TEST_NAME" "FAIL" "Error ejecución"
|
||||
fi
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚨 Troubleshooting
|
||||
|
||||
### "Chrome crashed" o "Can't find Chrome"
|
||||
|
||||
```bash
|
||||
# Ubuntu/Debian
|
||||
sudo apt-get install google-chrome-stable
|
||||
|
||||
# Verificar instalación
|
||||
google-chrome --version
|
||||
```
|
||||
|
||||
### "Permission denied" en scripts
|
||||
|
||||
```bash
|
||||
chmod +x test/*.sh
|
||||
chmod +x scripts/*.sh
|
||||
```
|
||||
|
||||
### Tests pasan localmente pero fallan en CI
|
||||
|
||||
```bash
|
||||
# Puede ser dependencia de Chrome
|
||||
# Verificar que Chrome se instala en CI (ver .github/workflows/test.yml)
|
||||
|
||||
# O diferencias de timezone/locale
|
||||
export TZ=UTC
|
||||
export LANG=en_US.UTF-8
|
||||
```
|
||||
|
||||
### Perfiles de test llenan disco
|
||||
|
||||
```bash
|
||||
# Limpiar automáticamente
|
||||
make clean
|
||||
|
||||
# O manualmente
|
||||
rm -rf test-profiles/
|
||||
rm -rf ~/.navegator/profiles/test-*
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 Métricas de Calidad
|
||||
|
||||
### Objetivos
|
||||
|
||||
- ✅ **Cobertura de código**: >70%
|
||||
- ✅ **Tests E2E**: >10 tests
|
||||
- ✅ **Tiempo de ejecución**: <5 minutos
|
||||
- ✅ **Pass rate**: >90%
|
||||
|
||||
### Monitorear
|
||||
|
||||
```bash
|
||||
# Tiempo de ejecución
|
||||
time make test
|
||||
|
||||
# Cobertura
|
||||
make coverage
|
||||
# Ver coverage.html
|
||||
|
||||
# Pass rate
|
||||
make test | grep "Pass rate"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Comandos Útiles
|
||||
|
||||
```bash
|
||||
# Ejecutar todo
|
||||
make test
|
||||
|
||||
# Solo tests rápidos
|
||||
make test-quick
|
||||
|
||||
# Solo E2E
|
||||
make test-e2e
|
||||
|
||||
# Solo integración
|
||||
make test-integration
|
||||
|
||||
# Con cobertura
|
||||
make coverage
|
||||
|
||||
# Limpiar todo
|
||||
make clean
|
||||
|
||||
# Ver ayuda
|
||||
make help
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📚 Recursos
|
||||
|
||||
- **Go Testing**: https://go.dev/doc/tutorial/add-a-test
|
||||
- **Table-driven tests**: https://go.dev/wiki/TableDrivenTests
|
||||
- **CI/CD con GitHub Actions**: https://docs.github.com/actions
|
||||
|
||||
---
|
||||
|
||||
## ✅ Checklist Pre-Commit
|
||||
|
||||
Antes de hacer commit, ejecutar:
|
||||
|
||||
```bash
|
||||
□ make fmt # Formatear código
|
||||
□ make lint # Verificar código
|
||||
□ make test-quick # Tests rápidos
|
||||
□ make test # Tests completos (si hay tiempo)
|
||||
```
|
||||
|
||||
Antes de hacer PR:
|
||||
|
||||
```bash
|
||||
□ make test # Todos los tests
|
||||
□ make coverage # Verificar cobertura
|
||||
□ Revisar CI/CD # Ver que pase en GitHub Actions
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Conclusión
|
||||
|
||||
Con este sistema de testing puedes:
|
||||
|
||||
✅ Verificar que los binarios funcionan correctamente
|
||||
✅ Detectar regresiones automáticamente
|
||||
✅ Validar cambios antes de deploy
|
||||
✅ Mantener calidad de código alta
|
||||
✅ CI/CD automático en cada push
|
||||
|
||||
**Comando más importante:**
|
||||
```bash
|
||||
make test
|
||||
```
|
||||
|
||||
Ejecuta todo: unitarios, E2E, integración. Si pasa, el código está listo.
|
||||
Reference in New Issue
Block a user