From 76f2bbaca21281f6ca17e3a6f02c16328299e787 Mon Sep 17 00:00:00 2001 From: marsalva Date: Thu, 19 Feb 2026 08:21:40 +0000 Subject: [PATCH] Actualizar robot.js --- robot.js | 131 +++++++++++++------------------------------------------ 1 file changed, 31 insertions(+), 100 deletions(-) diff --git a/robot.js b/robot.js index d721c01..f1e9c1f 100644 --- a/robot.js +++ b/robot.js @@ -122,7 +122,7 @@ async function main() { } // ========================================== -// šŸ„ MULTIASISTENCIA (CON INTELIGENCIA Y PAGINACIƓN) +// šŸ„ MULTIASISTENCIA (CON INTELIGENCIA Y PAGINACIƓN REAL) // ========================================== async function runMultiasistencia(ownerId, user, pass, gremiosDB) { const browser = await chromium.launch({ headless: HEADLESS, args: ['--no-sandbox'] }); @@ -144,7 +144,7 @@ async function runMultiasistencia(ownerId, user, pass, gremiosDB) { while (true) { console.log(`šŸ“„ [Multi] Escaneando pĆ”gina ${paginaActual}...`); - // Extraer expedientes de esta pĆ”gina + // 1. Extraer expedientes de la pĆ”gina actual const expedientesPagina = await page.evaluate(() => { const links = Array.from(document.querySelectorAll('a[href*="reparacion="]')); return links.map(a => a.href.match(/reparacion=(\d+)/)?.[1]).filter(Boolean); @@ -152,54 +152,64 @@ async function runMultiasistencia(ownerId, user, pass, gremiosDB) { expedientesPagina.forEach(ref => todosExpedientes.add(ref)); - // Buscar botón de siguiente pĆ”gina y hacer clic si existe - const clickedNext = await page.evaluate(() => { - const links = Array.from(document.querySelectorAll('a')); - const nextBtn = links.find(a => { - const txt = a.innerText.trim(); - const title = (a.title || "").toLowerCase(); - return txt === '>' || txt.toLowerCase() === 'siguiente' || title.includes('siguient') || a.querySelector('img[alt*="iguient"]'); - }); + // 2. Buscar el botón "PĆ”gina siguiente" + // Basado en el HTML: PĆ”gina siguiente + const hasNextPage = await page.evaluate(() => { + const links = Array.from(document.querySelectorAll('a.lnkheader')); + const nextBtn = links.find(a => a.innerText.trim() === 'PĆ”gina siguiente'); if (nextBtn) { - nextBtn.click(); + nextBtn.click(); // Ejecuta el javascript interno de la web return true; } return false; }); - if (clickedNext) { - await page.waitForTimeout(3000); // Dar tiempo a que cargue la siguiente pĆ”gina + if (hasNextPage) { + // Esperamos a que la red se calme tras el submit del formulario de la web + await page.waitForLoadState('networkidle'); + await page.waitForTimeout(2000); // Un pequeƱo margen extra paginaActual++; + + // Medida de seguridad antbucle infinito + if(paginaActual > 15) { + console.log("āš ļø [Multi] LĆ­mite de 15 pĆ”ginas alcanzado por seguridad."); + break; + } } else { - break; // Se acabaron las pĆ”ginas + console.log("šŸ›‘ [Multi] No hay mĆ”s pĆ”ginas."); + break; // Se acabó la paginación } } const expedientes = Array.from(todosExpedientes); - console.log(`āœ… [Multi] Total expedientes detectados: ${expedientes.length}`); + console.log(`āœ… [Multi] Total expedientes Ćŗnicos detectados: ${expedientes.length}`); // --- MEJORA: ARCHIVADO --- if (expedientes.length > 0) { await syncAndArchive(ownerId, 'multiasistencia', expedientes); } + // --- EXTRACCIƓN DE DATOS --- for (const ref of expedientes) { await page.goto(`https://web.multiasistencia.com/w3multi/repasos1.php?reparacion=${ref}`, { waitUntil: 'domcontentloaded' }); await page.waitForTimeout(1500); let scrapData = null; + for (const frame of page.frames()) { try { scrapData = await frame.evaluate(() => { const clean = (t) => t ? t.replace(/\s+/g, ' ').trim() : ""; const body = document.body?.innerText || ""; if (!body.includes("Nombre Cliente") && !body.includes("Asegurado")) return null; + const cabeceras = Array.from(document.querySelectorAll('.tcab')); const detalles = Array.from(document.querySelectorAll('.tdet')); const findByCab = (texto) => { const idx = cabeceras.findIndex(el => el.innerText.includes(texto)); return idx !== -1 && detalles[idx] ? clean(detalles[idx].innerText) : null; }; + let rawDesc = ""; const descHeader = Array.from(document.querySelectorAll('td.tcab')).find(td => td.innerText.includes("Descripción de la Reparación")); if (descHeader && descHeader.nextElementSibling) rawDesc = clean(descHeader.nextElementSibling.innerText); @@ -226,6 +236,7 @@ async function runMultiasistencia(ownerId, user, pass, gremiosDB) { if (scrapData && scrapData['Nombre Cliente']) break; } catch (e) { continue; } } + if (scrapData && scrapData['Nombre Cliente']) { // šŸŖ„ MAGIA: Clasificamos el gremio basĆ”ndonos en la descripción leĆ­da de la web const idGremioDetectado = clasificarGremio(scrapData['Descripción'], gremiosDB); @@ -235,91 +246,11 @@ async function runMultiasistencia(ownerId, user, pass, gremiosDB) { await saveServiceToDB(ownerId, 'multiasistencia', ref, scrapData); } } - } catch (e) { console.error("āŒ Error Multi:", e.message); } finally { await browser.close(); } -} - -// ========================================== -// 🧹 HOMESERVE (CON INTELIGENCIA) -// ========================================== -async function runHomeserve(ownerId, user, pass, gremiosDB) { - const browser = await chromium.launch({ headless: HEADLESS, args: ['--no-sandbox'] }); - const page = await browser.newPage(); - try { - console.log("šŸŒ [HomeServe] Entrando..."); - await page.goto('https://www.clientes.homeserve.es/cgi-bin/fccgi.exe?w3exec=PROF_PASS', { timeout: 60000 }); - - if (await page.isVisible('input[name="CODIGO"]')) { - await page.fill('input[name="CODIGO"]', user); - await page.fill('input[type="password"]', pass); - await page.keyboard.press('Enter'); - await page.waitForTimeout(5000); - } - - await page.goto('https://www.clientes.homeserve.es/cgi-bin/fccgi.exe?w3exec=lista_servicios_total'); - await page.waitForTimeout(3000); - - const refs = await page.evaluate(() => { - const cells = Array.from(document.querySelectorAll('td')); - const found = []; - cells.forEach(td => { - const match = td.innerText.trim().match(/^15\d{6}$/); - if (match) found.push(match[0]); - }); - return [...new Set(found)]; - }); - - // --- MEJORA: ARCHIVADO --- - if (refs.length > 0) { - await syncAndArchive(ownerId, 'homeserve', refs); - } - - console.log(`šŸ” [HomeServe] ${refs.length} expedientes detectados.`); - - for (const ref of refs) { - await page.goto(`https://www.clientes.homeserve.es/cgi-bin/fccgi.exe?w3exec=ver_servicioencurso&Servicio=${ref}`); - await page.waitForTimeout(2000); - - const scrapData = await page.evaluate(() => { - const d = {}; - const rows = Array.from(document.querySelectorAll('tr')); - rows.forEach(r => { - const cells = r.querySelectorAll('td'); - if (cells.length >= 2) { - const k = cells[0].innerText.toUpperCase().trim().replace(':', ''); - const v = cells[1].innerText.trim(); - if (k.includes("COMENTARIOS")) { - const txt = cells[1].querySelector('textarea')?.value || ""; - const cleanDesc = txt.split('\n').filter(line => { - const l = line.toUpperCase(); - return !["CAMBIO DE ESTADO", "ESTADO ASIGNADO", "SMS NO ENVIADO", "CONTACTO CON PROF", "0000"].some(b => l.includes(b)); - }).slice(0, 3).join('\n').trim(); - d['Descripción'] = cleanDesc; - } else if (k.length > 1 && v.length > 0 && !k.includes("MENU")) { - d[k] = v; - } - } - }); - const rawPop = d['POBLACION-PROVINCIA'] || ""; - const cpMatch = rawPop.match(/\b\d{5}\b/); - d['Código Postal'] = cpMatch ? cpMatch[0] : ""; - d['Población'] = rawPop.replace(d['Código Postal'], '').replace('-', '').trim(); - d['CompaƱƭa'] = "HOME - " + (d['COMPAƑIA'] || "HOMESERVE"); - d['Nombre Cliente'] = d['CLIENTE'] || ""; - d['Dirección'] = d['DOMICILIO'] || ""; - return d; - }); - - if (scrapData && scrapData['Nombre Cliente']) { - // šŸŖ„ MAGIA: Clasificamos el gremio basĆ”ndonos en la descripción leĆ­da de la web - const idGremioDetectado = clasificarGremio(scrapData['Descripción'], gremiosDB); - if (idGremioDetectado) { - scrapData['guild_id'] = idGremioDetectado; - } - await saveServiceToDB(ownerId, 'homeserve', ref, scrapData); - } - } - } catch (e) { console.error("āŒ [HomeServe] Error:", e.message); } - finally { await browser.close(); } + } catch (e) { + console.error("āŒ Error Multi:", e.message); + } finally { + await browser.close(); + } } // --- NUEVA FUNCIƓN: SINCRONIZACIƓN Y ARCHIVADO ---