puppeteer 中 element.click() 的问题
我遇到了以下问题。如果我运行此代码,我会收到此错误消息,而且似乎无法修复它。
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();
这个相当棘手。我不知道为什么,但是页面上有一些奇怪的可见性和事件处理特性,所以我基本上是通过尝试可信和不可信的事件来进行点击和选择的“暴力破解”的。
对于选择器触发器(尺寸选择下拉菜单),我使用了不可信的事件。选择尺寸最适合使用可信事件,而添加到购物车最适合使用可信事件。这些可能不是硬性规定,所以我可能错过了一些东西,但下面的代码应该可以捕获购物车中商品的屏幕截图。
我还发现 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())
;
您正在执行
await page.$$eval('.example')
不确定是否有任何元素
example
,并且
.find
不保证返回任何值。始终执行
if
检查
const element = elements.find(element => element.innerHTML === '39');
if (element){
element.click();
}
MDN 关于
find
-
find()
方法返回所提供数组中满足所提供测试函数的第一个元素。如果没有值满足测试函数,则返回
undefined
。