Soy nuevo en js y he estado intentando durante horas obtener el texto interno de la etiqueta bio__name__display (ver el DOM adjunto) y estoy fallando. Cual podría ser el problema aquí?
Estoy llamando a las funciones asíncronas definidas en page.js desde index.js , y cuando console.log el valor de retorno de una primera función, funciona bien. Sin embargo, la segunda función no funciona (la salida no está undefined ).
Para CSS Selector, probé lo siguiente pero fue en vano.
div.bio__name > span.bio__name__display"div.bio__name>span.bio__name__display"div.bio__name span.bio__name__display const splinterlandsPage= require('./page'); . . . await page.waitForTimeout(10000); let [mana, displayName] = await Promise.all([ splinterlandsPage.checkMatchMana(page).then((mana) => mana).catch(() => 'no mana'), splinterlandsPage.getText(page).then((displayName) => displayName).catch(() => 'displayName name not caught') ]); console.log("mana : ", mana) //works console.log("displayName: ", displayName); //does not work . . . . . . // first function async function checkMatchMana(page) { const mana = await page.$$eval("div.col-md-12 > div.mana-cap__icon", el => el.map(x => x.getAttribute("data-original-title"))); const manaValue = parseInt(mana[0].split(':')[1], 10); return manaValue; } // second function async function getText(page) { const displayName= await page.$$eval("div.bio__name > span.bio__name__display", el => el.innerText); return displayName } . . . exports.checkMatchMana = checkMatchMana; exports.getText= getText;Por mucho que quisiera compartir la URL real del sitio, fue difícil hacerlo ya que el acceso al DOM requería registrarse en el sitio y este DOM específico en cuestión está disponible solo 2 minutos después de un botón determinado dentro del se hace clic en el sitio.
Finalmente los descubrí yo mismo hoy; a continuación hay una solución y algunas notas para referencia posterior.
El problema no era un selector de CSS sino lo que devolvía $$eval .
Dado que $$eval devuelve una lista de elementos, el valor devuelto debe procesarse como el => el.map(x => x.innerText)) en lugar de el => el.innerText .
// second function async function getText(page) { const displayName = await page.$$eval("div.bio__name > span.bio__name__display", el => el.map(x => x.innerText)); return displayName[0] } Otra solución alternativa puede ser usar $eval en su lugar, que devuelve un solo elemento coincidente.
// second function async function getText(page) { const displayName = await page.$eval("div.bio__name > span.bio__name__display", el => el.innerText); return displayName }$$eval y $eval $$eval ejecuta document.querySelectorAll('CSS Selector') internamente, lo que devuelve varios elementos que coinciden con el grupo de selectores especificado.
( También funciona cuando solo hay un elemento que coincide, pero el valor devuelto debe procesarse en consecuencia en pageFunction[, ...args] )
$eval ejecuta document.querySelector('CSS Selector') internamente, lo que devuelve un único elemento que coincide con el grupo de selectores especificado.
Como nuevo aprendiz, a menudo me encuentro perdido tratando de elegir los selectores correctos.
Puede ser una forma rápida y sucia, pero la primera respuesta a esta pregunta ayudó.