Puppeteer处理表单俱乐部选择弹窗时出现Unknown key: 'OK'错误
嘿,我看到你遇到的问题了——你在处理俱乐部选择后的弹窗时用了page.keyboard.press("OK"),结果触发了这个错误:
Error: Unknown key: "OK"
at assert (C:\puppeteer-project\node_modules\puppeteer-core\lib\cjs\puppeteer\util\assert.js:18:15)
at #keyDescriptionForString (C:\puppeteer-project\node_modules\puppeteer-core\lib\cjs\puppeteer\cdp\Input.js:75:32)
at CdpKeyboard.down (C:\puppeteer-project\node_modules\puppeteer-core\lib\cjs\puppeteer\cdp\Input.js:31:58)
at CdpKeyboard.press (C:\puppeteer-project\node_modules\puppeteer-core\lib\cjs\puppeteer\cdp\Input.js:146:20)
这是因为page.keyboard.press()这个方法是用来模拟物理键盘按键的,比如Enter、Space、Escape这类按键名称,它根本不认识弹窗上的按钮文本"OK",所以才会抛出"Unknown key"的错误。
接下来给你两种正确处理这类alert弹窗的方法:
方法一:提前监听弹窗事件
在操作可能触发弹窗的元素之前,先给页面绑定dialog事件监听,这样弹窗出现时就能自动捕获并处理:
const { normalize } = require("path"); const { join } = require("path/posix"); const puppeteer = require("puppeteer"); (async () => { const browser = await puppeteer.launch({ headless: false }); const page = await browser.newPage(); // 提前监听弹窗,自动点击"OK" page.on("dialog", async (dialog) => { console.log(`弹窗提示: ${dialog.message()}`); await dialog.accept(); // 调用accept()就是点击弹窗的确认按钮 }); await page.goto("https://url/membership/join"); await page.type("#email", "wise4rmgod@yahoo.com"); await page.type("#first-name", "Johnxxx"); await page.type("#last-name", "Doezzz"); await page.type("#password", "Password&123"); await page.type("#confirm-password", "Password&123"); // 选择俱乐部,触发弹窗 await page.select("#club", "Sample Club Name"); // 触发注册按钮(这里要替换成你页面上注册按钮的实际选择器) // await page.click("button[type='submit']"); // await page.waitForNavigation(); console.log("Successfully signed in!"); // await browser.close(); })();
方法二:主动等待弹窗出现
如果你只想处理这一次弹窗,可以先创建一个等待弹窗的Promise,再执行触发弹窗的操作,最后处理弹窗:
const { normalize } = require("path"); const { join } = require("path/posix"); const puppeteer = require("puppeteer"); (async () => { const browser = await puppeteer.launch({ headless: false }); const page = await browser.newPage(); await page.goto("https://url/membership/join"); await page.type("#email", "wise4rmgod@yahoo.com"); await page.type("#first-name", "Johnxxx"); await page.type("#last-name", "Doezzz"); await page.type("#password", "Password&123"); await page.type("#confirm-password", "Password&123"); // 先创建等待弹窗的Promise const dialogPromise = page.waitForDialog(); // 选择俱乐部,触发弹窗 await page.select("#club", "Sample Club Name"); // 等待弹窗出现并捕获 const dialog = await dialogPromise; // 点击确认按钮 await dialog.accept(); // 触发注册按钮 // await page.click("#register"); // await page.waitForNavigation(); console.log("Successfully signed in!"); // await browser.close(); })();
另外还要提醒你两个小问题:
- 你代码里的
setTimeout(demo, 10000);中demo函数并没有定义,这会导致额外的错误,建议去掉或者补充这个函数的实现。 - 注释里的
await page.keyboard.press("register");也是错误的,触发按钮应该用page.click(),并传入按钮的正确选择器,比如#register或者对应的CSS选择器。
备注:内容来源于stack exchange,提问作者Terry Palmer




