Playwright点击元素触发locator.click: Target closed错误求助
问题分析与解决方案
错误原因
你遇到的locator.click: Target closed错误,核心是异步操作未正确等待以及页面导航与元素点击的时序冲突:
- 调用
page.locator().click()时未加await,这是异步方法,未等点击完成就执行waitForNavigation,导致页面开始导航后,原页面的「下一页」元素被销毁,此时点击操作仍在尝试访问已关闭的元素目标。 waitForNavigation调用时机滞后,没有和点击操作同步,容易错过导航触发时机,或在元素已失效后才执行等待逻辑。
修复后的代码
await page.goto(url, { waitUntil: "networkidle" }); let totalPages = 2; for (let p = 1; p <= totalPages; p++) { // 处理当前页内容 let all = await page.$$("div.course-card--container--1QM2W"); for (let i = 0; i < all.length; i++) { let element = await all[i].innerHTML(); // $$返回ElementHandle数组,无需asElement() let $ = cheerio.load(element); // cheerio.load是同步方法,无需await let texts = $("div .course-card--instructor-list--nH1OC").text(); // 可添加texts的处理逻辑,比如打印、存储等 } // 最后一页无需点击下一页,避免无效操作 if (p < totalPages) { // 推荐方式:用click内置的导航等待,确保点击与导航同步 await page.locator("a.pagination--next--BrXhF").click({ waitUntil: "networkidle" // 可根据需求替换为load/domcontentloaded }); // 兼容旧版本Playwright的写法:先启动导航等待,再执行点击 // const navigationPromise = page.waitForNavigation({ waitUntil: "networkidle" }); // await page.locator("a.pagination--next--BrXhF").click(); // await navigationPromise; } }
额外优化点
- 去掉冗余的
asElement():page.$$()返回的本身就是ElementHandle数组,直接调用innerHTML()即可。 - 移除
cheerio.load()前的await:该方法是同步执行的,无需等待。 - 增加分页边界判断:避免最后一页重复点击「下一页」按钮,减少无效操作风险。
内容的提问来源于stack exchange,提问作者Vivek
相关产品推荐
相关产品推荐

