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"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"time"
|
|
||||||
|
|
||||||
"navegator/pkg/browser"
|
"navegator/pkg/browser"
|
||||||
)
|
)
|
||||||
@@ -67,13 +66,13 @@ func main() {
|
|||||||
searchURL := fmt.Sprintf("https://duckduckgo.com/?q=%s", *query)
|
searchURL := fmt.Sprintf("https://duckduckgo.com/?q=%s", *query)
|
||||||
log.Println("🌐 Navegando a DuckDuckGo...")
|
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)
|
log.Fatalf("❌ Error al navegar: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Esperar a que carguen los resultados
|
|
||||||
time.Sleep(3 * time.Second)
|
|
||||||
|
|
||||||
log.Println("📥 Extrayendo resultados...")
|
log.Println("📥 Extrayendo resultados...")
|
||||||
|
|
||||||
// Script para extraer resultados
|
// Script para extraer resultados
|
||||||
|
|||||||
+4
-5
@@ -8,7 +8,6 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"time"
|
|
||||||
|
|
||||||
"navegator/pkg/browser"
|
"navegator/pkg/browser"
|
||||||
)
|
)
|
||||||
@@ -85,13 +84,13 @@ func main() {
|
|||||||
searchURL := fmt.Sprintf("https://duckduckgo.com/?q=%s", *query)
|
searchURL := fmt.Sprintf("https://duckduckgo.com/?q=%s", *query)
|
||||||
log.Println("🌐 Navegando a DuckDuckGo...")
|
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)
|
log.Fatalf("❌ Error al navegar: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Esperar a que carguen los resultados
|
|
||||||
time.Sleep(3 * time.Second)
|
|
||||||
|
|
||||||
log.Println("📥 Extrayendo resultados...")
|
log.Println("📥 Extrayendo resultados...")
|
||||||
|
|
||||||
// Script para extraer 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")
|
log.Println("✅ Página cargada")
|
||||||
}
|
}
|
||||||
|
|
||||||
time.Sleep(2 * time.Second)
|
|
||||||
|
|
||||||
// Click si se especificó
|
// Click si se especificó
|
||||||
if *click != "" {
|
if *click != "" {
|
||||||
b.AddComment(fmt.Sprintf("Click en: %s", *click))
|
b.AddComment(fmt.Sprintf("Click en: %s", *click))
|
||||||
@@ -90,7 +88,6 @@ func main() {
|
|||||||
log.Printf("⚠️ Error al hacer click: %v", err)
|
log.Printf("⚠️ Error al hacer click: %v", err)
|
||||||
} else {
|
} else {
|
||||||
log.Println("✅ Click realizado")
|
log.Println("✅ Click realizado")
|
||||||
time.Sleep(2 * time.Second)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,7 +99,6 @@ func main() {
|
|||||||
log.Printf("⚠️ Error al escribir: %v", err)
|
log.Printf("⚠️ Error al escribir: %v", err)
|
||||||
} else {
|
} else {
|
||||||
log.Println("✅ Texto escrito")
|
log.Println("✅ Texto escrito")
|
||||||
time.Sleep(2 * time.Second)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-6
@@ -2,10 +2,8 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"time"
|
|
||||||
|
|
||||||
"navegator/pkg/browser"
|
"navegator/pkg/browser"
|
||||||
)
|
)
|
||||||
@@ -33,13 +31,12 @@ func main() {
|
|||||||
|
|
||||||
// Navegar a una página
|
// Navegar a una página
|
||||||
log.Println("Navegando a example.com...")
|
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)
|
log.Fatalf("Error al navegar: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Esperar un poco para que cargue
|
|
||||||
time.Sleep(2 * time.Second)
|
|
||||||
|
|
||||||
// Obtener HTML
|
// Obtener HTML
|
||||||
log.Println("Obteniendo HTML...")
|
log.Println("Obteniendo HTML...")
|
||||||
html, err := b.GetHTML(ctx, "")
|
html, err := b.GetHTML(ctx, "")
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import (
|
|||||||
"os/signal"
|
"os/signal"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
|
||||||
|
|
||||||
"navegator/pkg/browser"
|
"navegator/pkg/browser"
|
||||||
)
|
)
|
||||||
@@ -64,7 +63,9 @@ func main() {
|
|||||||
// Navegar a página de prueba
|
// Navegar a página de prueba
|
||||||
b.AddComment("=== INICIO DE SESIÓN ===")
|
b.AddComment("=== INICIO DE SESIÓN ===")
|
||||||
log.Println("\n📍 Navegando a example.com...")
|
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)
|
log.Printf("❌ Error al navegar: %v", err)
|
||||||
} else {
|
} else {
|
||||||
log.Println("✅ Navegación completada")
|
log.Println("✅ Navegación completada")
|
||||||
@@ -72,8 +73,6 @@ func main() {
|
|||||||
|
|
||||||
b.AddComment("Página cargada correctamente")
|
b.AddComment("Página cargada correctamente")
|
||||||
|
|
||||||
time.Sleep(2 * time.Second)
|
|
||||||
|
|
||||||
// Obtener información de la página
|
// Obtener información de la página
|
||||||
log.Println("\n📊 Obteniendo información de la página...")
|
log.Println("\n📊 Obteniendo información de la página...")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user