From 7d5339acadb2b55b295fdfd7a16b63df028998a8 Mon Sep 17 00:00:00 2001 From: Developer Date: Wed, 25 Mar 2026 00:48:54 +0100 Subject: [PATCH] refactor: eliminar time.Sleep innecesarios MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- cmd/buscar.go | 9 ++- cmd/buscar_v2.go | 9 ++- cmd/list_blog.go | 151 ++++++++++++++++++++++++++++++++++++++++++++++ cmd/navegar.go | 4 -- examples/basic.go | 9 +-- main.go | 7 +-- 6 files changed, 165 insertions(+), 24 deletions(-) create mode 100644 cmd/list_blog.go diff --git a/cmd/buscar.go b/cmd/buscar.go index 1387efc..900e827 100644 --- a/cmd/buscar.go +++ b/cmd/buscar.go @@ -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 diff --git a/cmd/buscar_v2.go b/cmd/buscar_v2.go index 00db135..88a0213 100644 --- a/cmd/buscar_v2.go +++ b/cmd/buscar_v2.go @@ -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 diff --git a/cmd/list_blog.go b/cmd/list_blog.go new file mode 100644 index 0000000..8b29493 --- /dev/null +++ b/cmd/list_blog.go @@ -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() + } + } +} diff --git a/cmd/navegar.go b/cmd/navegar.go index 76017ec..cc568b8 100644 --- a/cmd/navegar.go +++ b/cmd/navegar.go @@ -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) } } diff --git a/examples/basic.go b/examples/basic.go index 4a9562a..515b631 100644 --- a/examples/basic.go +++ b/examples/basic.go @@ -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, "") diff --git a/main.go b/main.go index b1baed8..19d8f8a 100644 --- a/main.go +++ b/main.go @@ -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...")