开发者问题收集

puppeteer 中 element.click() 的问题

2022-05-10
1905

我遇到了以下问题。如果我运行此代码,我会收到此错误消息,而且似乎无法修复它。

Uncaught Error Error: Evaluation failed: TypeError: Cannot read properties of undefined (reading 'click') at _evaluateInternal (c:\Users\Name\node_modules\puppeteer\lib\cjs\puppeteer\common\ExecutionContext.js:221:19) at processTicksAndRejections (node: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();
2个回答

这个相当棘手。我不知道为什么,但是页面上有一些奇怪的可见性和事件处理特性,所以我基本上是通过尝试可信和不可信的事件来进行点击和选择的“暴力破解”的。

对于选择器触发器(尺寸选择下拉菜单),我使用了不可信的事件。选择尺寸最适合使用可信事件,而添加到购物车最适合使用可信事件。这些可能不是硬性规定,所以我可能错过了一些东西,但下面的代码应该可以捕获购物车中商品的屏幕截图。

我还发现 cookie 横幅似乎会破坏下拉菜单。等待并关闭它提高了脚本的可靠性,但我最终将其注释掉,以提高速度,并且因为这可能不是必要的。不过,我没有进行足够的运行来确定,所以它留在下面的代码中。

这是代码:

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())
;
ggorlen
2022-05-11

您正在执行

await page.$$eval('.example')

不确定是否有任何元素 example ,并且 .find 不保证返回任何值。始终执行 if 检查

const element = elements.find(element => element.innerHTML === '39');

if (element){
 element.click();
}

MDN 关于 find - find() 方法返回所提供数组中满足所提供测试函数的第一个元素。如果没有值满足测试函数,则返回 undefined

Shivam
2022-05-10