如何在Selenium Python中处理Alert弹窗?解决NoAlertPresentException报错
Selenium处理Alert弹窗时的异常问题
我用Python结合Selenium编写自动化脚本,循环读取Excel文件中的数据,调用test_getcaf函数执行网站数据搜索与文件获取操作。点击搜索按钮后可能弹出仅含“OK”选项的Alert弹窗,但运行脚本时,捕获UnexpectedAlertPresentException异常后执行driver.switch_to.alert.accept(),却触发NoAlertPresentException报错。尝试过使用else、finally语句,以及判断driver.switch_to.alert是否存在的方法,均未解决问题,请问哪里操作有误?
我的Python脚本
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.firefox.options import Options from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.common import exceptions from selenium.webdriver.common.alert import Alert import openpyxl options = Options() options.set_preference("browser.download.folderList", 2) options.set_preference("browser.download.manager.showWhenStarting", False) options.set_preference("browser.download.dir", "D:\\Path\\Script") options.set_preference("browser.helperApps.neverAsk.saveToDisk", "application/x-gzip") driver = webdriver.Firefox(options=options) def test_getcaf(number, ptype): number = str(number) ptype = str(ptype) driver.switch_to.default_content() driver.implicitly_wait(1) driver.switch_to.frame("bodyframe") # switch to selected iframe textbox_MobileNo = driver.find_element(by=By.ID, value="txtMobileNo") textbox_ptype = driver.find_element(by=By.ID, value="ptype") textbox_MobileNo.send_keys(number) textbox_ptype.send_keys(ptype) try: search_button = driver.find_element(By.ID, value="mainTable") search_button.click() #This click can or cannot generate an alter box show_button = driver.find_element(By.CSS_SELECTOR, "table#deletelink tbody tr td.view_icon") show_button.click() return True except exceptions.UnexpectedAlertPresentException: driver.switch_to.alert.accept() return False wb_obj = openpyxl.load_workbook("D:\\Path\\Book1.xlsx") sheet_obj = wb_obj.active row = sheet_obj.max_row+1 column = sheet_obj.max_column+1 # Passing the value to the function for i in range(2, row): Mob_num = sheet_obj.cell(row=i, column=1).value Mob_type = sheet_obj.cell(row=i, column=2).value Return_messag = test_getcaf(Mob_num,Mob_type) sheet_obj.cell(row=i, column=3).value = Return_messag wb_obj.save("D:\\Path\\Book1.xlsx")
报错信息
selenium.common.exceptions.UnexpectedAlertPresentException: Alert Text: None Message: Dismissed user prompt dialog: Customer details not found with the specified search Stacktrace: RemoteError@chrome://remote/content/shared/RemoteError.sys.mjs:8:8 WebDriverError@chrome://remote/content/shared/webdriver/Errors.sys.mjs:187:5 UnexpectedAlertOpenError@chrome://remote/content/shared/webdriver/Errors.sys.mjs:704:5 GeckoDriver.prototype._handleUserPrompts@chrome://remote/content/marionette/driver.sys.mjs:2832:13 During handling of the above exception, another exception occurred: Traceback (most recent call last): File "D:\Search CAF\CCMS\test_fire.py", line 110, in <module> Return_messag = test_getcaf(Mob_num,Mob_type) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "D:\Search CAF\CCMS\test_fire.py", line 74, in test_getcaf driver.switch_to.alert.accept() ^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\JTOITWB\AppData\Local\Programs\Python\Python311\Lib\site-packages\selenium\webdriver\remote\switch_to.py", line 55, in alert _ = alert.text ^^^^^^^^^^ File "C:\Users\JTOITWB\AppData\Local\Programs\Python\Python311\Lib\site-packages\selenium\webdriver\common\alert.py", line 59, in text return self.driver.execute(Command.W3C_GET_ALERT_TEXT)["value"] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\JTOITWB\AppData\Local\Programs\Python\Python311\Lib\site-packages\selenium\webdriver\remote\webdriver.py", line 346, in execute self.error_handler.check_response(response) File "C:\Users\JTOITWB\AppData\Local\Programs\Python\Python311\Lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 245, in check_response raise exception_class(message, screen, stacktrace) selenium.common.exceptions.NoAlertPresentException: Message: Stacktrace: RemoteError@chrome://remote/content/shared/RemoteError.sys.mjs:8:8 WebDriverError@chrome://remote/content/shared/webdriver/Errors.sys.mjs:187:5 NoSuchAlertError@chrome://remote/content/shared/webdriver/Errors.sys.mjs:489:5 GeckoDriver.prototype._checkIfAlertIsPresent@chrome://remote/content/marionette/driver.sys.mjs:2803:11 GeckoDriver.prototype.getTextFromDialog@chrome://remote/content/marionette/driver.sys.mjs:2751:8 despatch@chrome://remote/content/marionette/server.sys.mjs:320:40 execute@chrome://remote/content/marionette/server.sys.mjs:291:16 onPacket/<@chrome://remote/content/marionette/server.sys.mjs:264:20 onPacket@chrome://remote/content/marionette/server.sys.mjs:265:9 _onJSONObjectReady/<@chrome://remote/content/marionette/transport.sys.mjs:496:20
问题根源与修复方案
问题本质
从报错信息里的Dismissed user prompt dialog能看出:Alert已经被GeckoDriver自动关闭了。当你点击搜索按钮后,GeckoDriver检测到弹窗并默认处理了它,等你捕获UnexpectedAlertPresentException再去调用driver.switch_to.alert时,弹窗已经不存在,所以触发NoAlertPresentException。
修复方法
1. 主动等待并处理Alert(推荐方案)
不要等异常抛出再处理,而是在点击搜索按钮后,主动用显式等待检查是否有Alert弹出,这样能精准控制弹窗处理时机:
修改test_getcaf函数:
def test_getcaf(number, ptype): number = str(number) ptype = str(ptype) driver.switch_to.default_content() driver.switch_to.frame("bodyframe") # 先清空输入框,避免重复输入旧数据 textbox_MobileNo = driver.find_element(by=By.ID, value="txtMobileNo") textbox_MobileNo.clear() textbox_MobileNo.send_keys(number) textbox_ptype = driver.find_element(by=By.ID, value="ptype") textbox_ptype.clear() textbox_ptype.send_keys(ptype) search_button = driver.find_element(By.ID, value="mainTable") search_button.click() try: # 显式等待Alert出现,超时时间根据实际页面响应调整 alert = WebDriverWait(driver, 3).until(EC.alert_is_present()) alert.accept() return False except exceptions.TimeoutException: # 没有弹窗,等待显示按钮可点击后再操作 show_button = WebDriverWait(driver, 5).until( EC.element_to_be_clickable((By.CSS_SELECTOR, "table#deletelink tbody tr td.view_icon")) ) show_button.click() return True
2. 调整GeckoDriver的弹窗处理策略(可选)
可以尝试设置Firefox偏好,禁用自动处理弹窗:
options.set_preference("dom.disable_beforeunload", True) options.set_preference("dom.alert.enabled", True)
但这个方法兼容性不一定好,优先用第一种显式等待的方案。
3. 额外优化建议
- 全局设置一次
driver.implicitly_wait(10)(放在driver初始化后),不要在函数里反复设置,避免隐式等待和显式等待冲突。 - 所有元素操作尽量用显式等待确保元素可交互,减少因页面加载慢导致的错误。
- Excel操作可以先把所有数据读到列表里,批量处理后再一次性保存,减少磁盘IO次数,提升效率。
内容的提问来源于stack exchange,提问作者Nilesh
相关产品推荐
相关产品推荐

