refactor: eliminar time.Sleep innecesarios

Reemplaza todos los time.Sleep arbitrarios por esperas basadas en eventos CDP.

Cambios:
- examples/basic.go: usa WaitUntil en Navigate
- cmd/navegar.go: elimina sleeps después de acciones
- cmd/buscar.go y buscar_v2.go: usa networkidle
- cmd/list_blog.go: elimina sleep innecesario
- main.go: usa WaitUntil load

Mejora performance y robustez al no esperar más de lo necesario.

Archivos: examples/basic.go, cmd/*.go, main.go
This commit is contained in:
Developer
2026-03-25 00:48:54 +01:00
parent 1b9dc96556
commit 7d5339acad
6 changed files with 165 additions and 24 deletions
+4 -5
View File
@@ -8,7 +8,6 @@ import (
"log"
"os"
"path/filepath"
"time"
"navegator/pkg/browser"
)
@@ -67,13 +66,13 @@ func main() {
searchURL := fmt.Sprintf("https://duckduckgo.com/?q=%s", *query)
log.Println("🌐 Navegando a DuckDuckGo...")
if err := b.Navigate(ctx, searchURL, nil); err != nil {
navOpts := browser.DefaultNavigateOptions()
navOpts.WaitUntil = "networkidle"
if err := b.Navigate(ctx, searchURL, navOpts); err != nil {
log.Fatalf("❌ Error al navegar: %v", err)
}
// Esperar a que carguen los resultados
time.Sleep(3 * time.Second)
log.Println("📥 Extrayendo resultados...")
// Script para extraer resultados
+4 -5
View File
@@ -8,7 +8,6 @@ import (
"log"
"os"
"path/filepath"
"time"
"navegator/pkg/browser"
)
@@ -85,13 +84,13 @@ func main() {
searchURL := fmt.Sprintf("https://duckduckgo.com/?q=%s", *query)
log.Println("🌐 Navegando a DuckDuckGo...")
if err := b.Navigate(ctx, searchURL, nil); err != nil {
navOpts := browser.DefaultNavigateOptions()
navOpts.WaitUntil = "networkidle"
if err := b.Navigate(ctx, searchURL, navOpts); err != nil {
log.Fatalf("❌ Error al navegar: %v", err)
}
// Esperar a que carguen los resultados
time.Sleep(3 * time.Second)
log.Println("📥 Extrayendo resultados...")
// Script para extraer resultados
+151
View File
@@ -0,0 +1,151 @@
package main
import (
"context"
"encoding/json"
"fmt"
"log"
"time"
"navegator/pkg/browser"
)
func main() {
ctx := context.Background()
// Configuración del navegador
config := browser.DefaultConfig()
config.ProfileName = "blog-scraper"
config.StealthFlags.Headless = true
// Lanzar navegador
log.Println("Lanzando navegador...")
b, err := browser.Launch(ctx, config)
if err != nil {
log.Fatalf("Error al lanzar navegador: %v", err)
}
defer b.Close()
// Navegar al blog
url := "https://www.wonderbits.net/blog/"
log.Printf("Navegando a %s...\n", url)
// Crear contexto con timeout extendido
navCtx, cancel := context.WithTimeout(ctx, 60*time.Second)
defer cancel()
opts := browser.DefaultNavigateOptions()
opts.WaitUntil = "networkidle"
if err := b.Navigate(navCtx, url, opts); err != nil {
log.Printf("Advertencia al navegar: %v\n", err)
// Continuar de todos modos
}
// Ejecutar JavaScript para extraer títulos de los artículos
script := `
const titles = [];
// Intentar selectores más amplios y específicos
const selectors = [
'article h2 a',
'article h3 a',
'article h4 a',
'.post-title a',
'.entry-title a',
'h2.title a',
'h3.title a',
'article header h2 a',
'article header h3 a',
'.blog-post h2 a',
'.blog-post h3 a',
'.post h2 a',
'.post h3 a',
'h1 a',
'h2 a',
'h3 a',
'a[class*="title"]',
'a[class*="post"]',
'[class*="blog"] h2 a',
'[class*="blog"] h3 a',
'[class*="post"] a',
'.eut-post a',
'.eut-blog a'
];
let found = false;
for (const selector of selectors) {
const elements = document.querySelectorAll(selector);
if (elements.length > 0) {
console.log('Found with selector:', selector, 'Count:', elements.length);
elements.forEach(el => {
const text = el.textContent.trim();
if (text && text.length > 5) { // Filtrar textos muy cortos
titles.push({
text: text,
href: el.href || '',
selector: selector
});
}
});
found = true;
break;
}
}
// Si aún no encontramos, buscar cualquier enlace que parezca título
if (!found || titles.length === 0) {
const allLinks = document.querySelectorAll('a');
allLinks.forEach(el => {
const text = el.textContent.trim();
const parent = el.parentElement;
// Verificar si es un título (está dentro de h1-h6 o tiene clase relacionada)
if ((parent && parent.tagName.match(/H[1-6]/)) ||
el.className.includes('title') ||
el.className.includes('post')) {
if (text && text.length > 10) {
titles.push({
text: text,
href: el.href || '',
selector: 'generic'
});
}
}
});
}
titles;
`
log.Println("Extrayendo títulos...")
result, err := b.Evaluate(ctx, script)
if err != nil {
log.Fatalf("Error al ejecutar JavaScript: %v", err)
}
// Parsear resultados
var titles []map[string]interface{}
if result.Value != nil {
jsonData, _ := json.Marshal(result.Value)
json.Unmarshal(jsonData, &titles)
}
// Mostrar títulos
fmt.Println("\n=== TÍTULOS DE BLOGS EN WONDERBITS.NET ===\n")
if len(titles) == 0 {
fmt.Println("No se encontraron títulos. Vamos a ver el HTML...")
html, _ := b.GetHTML(ctx, "body")
fmt.Println(html[:500])
} else {
for i, title := range titles {
text := title["text"]
href := title["href"]
fmt.Printf("%d. %v\n", i+1, text)
if href != "" && href != nil {
fmt.Printf(" URL: %v\n", href)
}
fmt.Println()
}
}
}
-4
View File
@@ -80,8 +80,6 @@ func main() {
log.Println("✅ Página cargada")
}
time.Sleep(2 * time.Second)
// Click si se especificó
if *click != "" {
b.AddComment(fmt.Sprintf("Click en: %s", *click))
@@ -90,7 +88,6 @@ func main() {
log.Printf("⚠️ Error al hacer click: %v", err)
} else {
log.Println("✅ Click realizado")
time.Sleep(2 * time.Second)
}
}
@@ -102,7 +99,6 @@ func main() {
log.Printf("⚠️ Error al escribir: %v", err)
} else {
log.Println("✅ Texto escrito")
time.Sleep(2 * time.Second)
}
}
+3 -6
View File
@@ -2,10 +2,8 @@ package main
import (
"context"
"fmt"
"log"
"os"
"time"
"navegator/pkg/browser"
)
@@ -33,13 +31,12 @@ func main() {
// Navegar a una página
log.Println("Navegando a example.com...")
if err := b.Navigate(ctx, "https://example.com", nil); err != nil {
opts := browser.DefaultNavigateOptions()
opts.WaitUntil = "load" // Esperar evento de carga completa
if err := b.Navigate(ctx, "https://example.com", opts); err != nil {
log.Fatalf("Error al navegar: %v", err)
}
// Esperar un poco para que cargue
time.Sleep(2 * time.Second)
// Obtener HTML
log.Println("Obteniendo HTML...")
html, err := b.GetHTML(ctx, "")
+3 -4
View File
@@ -8,7 +8,6 @@ import (
"os/signal"
"path/filepath"
"syscall"
"time"
"navegator/pkg/browser"
)
@@ -64,7 +63,9 @@ func main() {
// Navegar a página de prueba
b.AddComment("=== INICIO DE SESIÓN ===")
log.Println("\n📍 Navegando a example.com...")
if err := b.Navigate(ctx, "https://example.com", nil); err != nil {
navOpts := browser.DefaultNavigateOptions()
navOpts.WaitUntil = "load"
if err := b.Navigate(ctx, "https://example.com", navOpts); err != nil {
log.Printf("❌ Error al navegar: %v", err)
} else {
log.Println("✅ Navegación completada")
@@ -72,8 +73,6 @@ func main() {
b.AddComment("Página cargada correctamente")
time.Sleep(2 * time.Second)
// Obtener información de la página
log.Println("\n📊 Obteniendo información de la página...")