Página de titiritero.evaluar querySelectorAll devuelve objetos vacíos
Estoy probando Titiritero. Este es un código de muestra que puede ejecutar: https://try-puppeteer.appspot.com/
El problema es que este código devuelve una serie de objetos vacíos:
[{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{ },{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{}, {},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{} ,{},{},{},{},{},{},{}]
¿Estoy cometiendo un error?
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://reddit.com/');
let list = await page.evaluate(() => {
return Promise.resolve(Array.from(document.querySelectorAll('.title')));
});
console.log(JSON.stringify(list))
await browser.close();
Los valores devueltos por la función de evaluación deben ser serializables en json. https://github.com/GoogleChrome/puppeteer/issues/303#issuecomment-322919968
la solución es extraer los valores href de los elementos y devolverlos.
await this.page.evaluate((sel) => {
let elements = Array.from(document.querySelectorAll(sel));
let links = elements.map(element => {
return element.href
})
return links;
}, sel);
Problema:
El valor de retorno page.evaluate()
debe ser serializable .
Según la documentación de Puppeteer , dice:
Si la función pasada a
page.evaluate
devuelve un valor no serializable , sepage.evaluate
resuelve enundefined
. El protocolo DevTools también admite la transferencia de algunos valores adicionales que no son serializables mediante los literalesJSON
:-0
,NaN
, , y bigint.Infinity
-Infinity
En otras palabras, no puede devolver un elemento del entorno DOM de la página al entorno Node.js porque están separados.
Solución:
Puede devolver un ElementHandle
, que es una representación de un elemento DOM en la página, al entorno Node.js.
Utilice page.$$()
para obtener una ElementHandle
matriz:
let list = await page.$$('.title');
De lo contrario, si desea extraer los href
valores de los elementos y devolverlos, puede utilizar page.$$eval()
:
let list = await page.$$eval('.title', a => a.href);
Me enfrenté a un problema similar y lo resolví así;
await page.evaluate(() =>
Array.from(document.querySelectorAll('.title'),
e => e.href));