Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

176
Vistas
Cómo obtener niños div usando titiritero

Estoy tratando de obtener elementos secundarios de un div usando titiritero.
este es mi código:

 const puppeteer = require('puppeteer'); const url = 'https://example.com/'; //browser initialization async function initBrowser() { const browser = await puppeteer.launch({ headless: false, }); return browser; } async function getPage(browser) { const page = await browser.newPage(); await page.goto(url); return page; } async function getNewMessage(page) { let els = []; els = await page.$$('div.class'); for (let i = 0; i < els.length; i++) { const imgSrc = await els[i] .$('div.class2') .$eval('img', (el) => el.getAttribute('src')); console.log(imgSrc); const link = await els[i].$eval('div.class3', (elem) => elem.texContent); console.log(link); } } async function loading() { const browser = await initBrowser(); const page = await getPage(browser); await getNewMessage(page); } loading();

la estructura de la página se ve así:

 <div class="class"> <div class="class2"> <img src="..."> </div> <div class="class3"> message </div> </div>

el error que me sale es:
Error: Error: no se pudo encontrar el selector de coincidencia de elementos "img".

De hecho, creo que descubrí cuál es el problema, porque en algunos casos obtengo la imagen. Creo que cuando trato de obtener la imagen, todavía se está cargando y no puedo atraparla.

about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

A este código le falta un await :

 const imgSrc = await els[i] .$('div.class2') .$eval('img', (el) => el.getAttribute('src'));

No es posible encadenar de esta manera, porque .$ devuelve una promesa que no se esperaba, por lo que está llamando a .$eval en una simple y antigua promesa de JS en lugar de una función Titiritero. La solución sería await cada nueva llamada de Titiritero en una línea separada y usar variables intermedias.

 const div = await els[i].$('div.class2'); const imgSrc = await div.$eval('img', (el) => el.getAttribute('src'));

Técnicamente, podría encadenar entre paréntesis y await s en línea, pero sería más difícil de leer:

 const imgSrc = await (await els[i].$('div.class2')) .$eval('img', (el) => el.getAttribute('src'));

Mejor aún es combinar ambos selectores en uno. No es necesario el procedimiento de dos pasos:

 const imgSrc = await div.$eval('div.class2 img', (el) => el.getAttribute('src'));

Siguiendo esa lógica un paso más allá, es posible que pueda omitir todos los selectores intermedios, usando un .$$eval por arreglo que desee construir. Opcionalmente, puede fusionarlos si sabe que tendrán la misma longitud:

 const puppeteer = require("puppeteer"); const html = `<div class="class"> <div class="class2"> <img src="..."> </div> <div class="class3"> message </div> </div>`.repeat(2); // repeat the structure for demonstration purposes let browser; (async () => { browser = await puppeteer.launch({headless: true}); const [page] = await browser.pages(); await page.setContent(html); await page.waitForSelector("div.class div.class2 img"); const imgSrcs = await page.$$eval( "div.class div.class2 img", els => els.map(e => e.getAttribute("src")) ); const textContents = await page.$$eval( "div.class div.class3", els => els.map(e => e.textContent) ); const data = imgSrcs.map((e, i) => ({ src: e, text: textContents[i] })); console.log(JSON.stringify(data, null, 2)); })() .catch(err => console.error(err)) .finally(() => browser?.close()) ;

Producción:

 [ { "src": "...", "text": "\n message\n " }, { "src": "...", "text": "\n message\n " } ]
about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda