7d5339acad
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
152 lines
3.4 KiB
Go
152 lines
3.4 KiB
Go
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()
|
|
}
|
|
}
|
|
}
|