Tengo el siguiente problema. Si ejecuto este código, aparece este mensaje de error y parece que no puedo solucionarlo.
Error no detectado Error: la evaluación falló: TypeError: no se pueden leer las propiedades de undefined (leyendo 'clic') en _evaluateInternal (c:\Users\Name\node_modules\puppeteer\lib\cjs\puppeteer\common\ExecutionContext.js:221:19) en processTicksAndRejections (nodo:internal/process/task_queues:96:5)
const puppeteer = require('puppeteer'); const url = "https://www.zalando.de/nike-sportswear-blazer-mid-77-sneaker-high-ni115n001-a13.html"; async function initBrowser() { const browser = await puppeteer.launch({ headless: false }); const page = await browser.newPage(); await page.goto(url); await page.screenshot({ path: 'example.png' }); return page; } async function addToCart(page) { await page.$eval('span[class="piG9a1 _1IcNq Uxq3DH QylWsg JCuRr_ RYghuO _7Cm1F9 ka2E9k uMhVZi FxZV-M"]', element => element.click()); await page.$$eval('.example', elements => { const element = elements.find(element => element.innerHTML === '39'); element.click(); }); await page.$eval('button[class="DJxzzA u9KIT8 uEg2FS U_OhzR ZkIJC- Vn-7c- FCIprz heWLCX JIgPn9 LyRfpJ pxpHHp Md_Vex NN8L-8 GTG2H9 MfX1a0 WCjo-q EKabf7 aX2-iv r9BRio mo6ZnF E6Km4r"]', element => element.click()); } async function checkout() { const page = await initBrowser(); await addToCart(page); } checkout();Tú lo estás haciendo
await page.$$eval('.example') No estoy seguro si hay algún example de elemento y no se garantiza que .find devuelva ningún valor. Hacer siempre if marca
const element = elements.find(element => element.innerHTML === '39'); if (element){ element.click(); } MDN on find : el método find() devuelve el primer elemento de la matriz proporcionada que satisface la función de prueba proporcionada. Si ningún valor satisface la función de prueba, se devuelve undefined .
Este fue bastante complicado. No estoy seguro de por qué, pero hay algunas características extrañas de visibilidad y manejo de eventos en la página, por lo que básicamente la "forcé brutamente" probando eventos confiables y no confiables para clics y selección.
Para el activador del selector (menú desplegable de selección de tamaño), utilicé un evento que no es de confianza. Seleccionar el tamaño funcionó mejor con un evento de confianza y agregarlo al carrito funcionó con un evento de confianza. Es posible que estas no sean reglas estrictas, por lo que es posible que me haya perdido algo, pero el código a continuación debería capturar una captura de pantalla del artículo en el carrito.
También descubrí que el banner de cookies parece descartar el menú desplegable. Esperar y descartarlo mejoró la confiabilidad del script, pero eventualmente lo comenté por velocidad y porque podría no ser necesario. Sin embargo, no hice suficientes ejecuciones para estar seguro, por lo que queda en el código a continuación.
Aquí está el código:
const puppeteer = require("puppeteer"); // ^13.5.1 let browser; (async () => { browser = await puppeteer.launch({headless: true}); const [page] = await browser.pages(); const ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36"; await page.setExtraHTTPHeaders({"Accept-Language": "en-US,en;q=0.9"}); await page.setUserAgent(ua); const url = "https://www.zalando.de/nike-sportswear-blazer-mid-77-sneaker-high-ni115n001-a13.html"; await page.goto(url, {waitUntil: "domcontentloaded"}); // optionally accept the cookie banner //const cookie = await page.waitForSelector("#uc-btn-accept-banner"); //await cookie.evaluate(el => el.click()); const picker = await page.waitForSelector("#picker-trigger"); await picker.evaluate(el => el.click()); await page.waitForFunction(() => [...document.querySelectorAll(".fOd40J._0xLoFW.JT3_zV.FCIprz.LyRfpJ")] .find(el => el.innerText === "39") ); const size = await page.evaluateHandle(() => [...document.querySelectorAll(".fOd40J._0xLoFW.JT3_zV.FCIprz.LyRfpJ")] .find(el => el.innerText === "39") ); await size.click(); await page.click(".U4aOaA > .DJxzzA"); await page.evaluate(() => window.scrollTo(0, 0)); await page.waitForFunction(() => document.querySelector('a[title="Your bag"]')?.textContent.startsWith("1") ); await page.goto("https://en.zalando.de/cart/"); await page.screenshot({path: "testing-in-bag.png"}); })() .catch(err => console.error(err)) .finally(() => browser?.close()) ;