Selenium中CLASS_NAME定位元素失败,如何点击Dismiss弹窗按钮?
无法定位Investopedia网站弹窗的Dismiss按钮?
问题背景
我用Python Selenium操作Investopedia网站,完成登录后始终无法定位并点击弹窗的Dismiss按钮,尝试了三种定位方法均失败,核对过元素HTML结构仍无进展。
我的代码
from selenium import webdriver import os import time from selenium.webdriver.common.by import By from selenium.webdriver.common.action_chains import ActionChains from selenium.webdriver.common.keys import Keys from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC os.environ['PATH'] += r'/usr/local/bin/geckodriver' browser = webdriver.Firefox() browser.get('https://www.investopedia.com/auth/realms/investopedia/protocol/openid-connect/auth?client_id=finance-simulator&redirect_uri=https%3A%2F%2Fwww.investopedia.com%2Fsimulator%2Fportfolio&state=84830f95-2e14-4468-87b6-45325beadf2c&response_mode=fragment&response_type=code&scope=openid&nonce=ffc0eff2-93bb-4c25-86f2-f0697898c85b') browser.set_window_size(1500, 500) browser.set_window_position(x=0, y=0) username=browser.find_element(By.ID, "username") username.send_keys("########") password = browser.find_element(By.ID, 'password') password.send_keys('#######') password.submit() ''' #First code tried WebDriverWait(browser, 30).until( EC.element_to_be_clickable( (By.CLASS_NAME, "pushly_popover-buttons-dismiss pushly-prompt-buttons-dismiss") , ) ) ''' ''' #Second code tried time.sleep(35) popup = browser.find_element(By.CLASS_NAME, "pushly_popover-buttons-dismiss pushly-prompt-buttons-dismiss") ''' #Third code tried time.sleep(35) popup = browser.find_element(By.XPATH,"//span[text()='Dismiss']") popup.click()
遇到的错误
#First tried raise TimeoutException(message, screen, stacktrace) selenium.common.exceptions.TimeoutException: Message: Stacktrace: WebDriverError@chrome://remote/content/shared/webdriver/Errors.jsm:188:5 NoSuchElementError@chrome://remote/content/shared/webdriver/Errors.jsm:400:5 element.find/</<@chrome://remote/content/marionette/element.js:292:16 #Second tried raise exception_class(message, screen, stacktrace) selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: .pushly_popover-buttons-dismiss pushly-prompt-buttons-dismiss Stacktrace: WebDriverError@chrome://remote/content/shared/webdriver/Errors.jsm:188:5 NoSuchElementError@chrome://remote/content/shared/webdriver/Errors.jsm:400:5 element.find/</<@chrome://remote/content/marionette/element.js:292:16 #third tried raise exception_class(message, screen, stacktrace) selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: //span[text()='Dismiss']
解决方案
核心问题分析
By.CLASS_NAME用法错误:该方法只能传入单个类名,多个类名需用By.CSS_SELECTOR,类名之间用.连接- 弹窗在独立iframe中:Pushly这类第三方弹窗通常会放在单独的iframe里,Selenium默认在主文档查找元素,必须先切换到对应iframe才能定位
time.sleep()不可靠:固定等待时间无法适配页面加载速度,显式等待能确保元素可操作后再执行点击
修正后的代码
from selenium import webdriver import os from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC os.environ['PATH'] += r'/usr/local/bin/geckodriver' browser = webdriver.Firefox() browser.get('https://www.investopedia.com/auth/realms/investopedia/protocol/openid-connect/auth?client_id=finance-simulator&redirect_uri=https%3A%2F%2Fwww.investopedia.com%2Fsimulator%2Fportfolio&state=84830f95-2e14-4468-87b6-45325beadf2c&response_mode=fragment&response_type=code&scope=openid&nonce=ffc0eff2-93bb-4c25-86f2-f0697898c85b') browser.set_window_size(1500, 500) browser.set_window_position(x=0, y=0) # 登录操作 username = browser.find_element(By.ID, "username") username.send_keys("########") password = browser.find_element(By.ID, 'password') password.send_keys('#######') password.submit() try: # 切换到弹窗所在的iframe WebDriverWait(browser, 20).until( EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR, "iframe[src*='pushly']")) ) # 显式等待并定位Dismiss按钮 dismiss_btn = WebDriverWait(browser, 20).until( EC.element_to_be_clickable((By.CSS_SELECTOR, ".pushly_popover-buttons-dismiss.pushly-prompt-buttons-dismiss")) ) dismiss_btn.click() # 切换回主文档 browser.switch_to.default_content() except Exception as e: print(f"处理弹窗时出错: {e}")
内容的提问来源于stack exchange,提问作者Deusnominus
相关产品推荐
相关产品推荐

