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:
+4
-5
@@ -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
@@ -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
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
@@ -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, "")
|
||||
|
||||
@@ -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...")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user