Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

175
Views
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 answers
Answer question

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!