You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 07:18:11