使用Python Selenium定位弹窗关闭按钮时点击错误的问题
问题描述
- 使用ChromeDriver打开指定轮胎网站时,尝试点击弹窗的“X”按钮关闭弹窗,但程序始终点击错误的按钮;
- 调试模式下,在
close_button变量行设置断点,手动等待弹窗出现后再执行,就能正确识别并关闭按钮; - 已尝试
By.TAG_NAME、By.ID、By.CLASS_NAME、By.CSS_SELECTOR等多种定位方式,问题仍未解决。
相关代码如下:
from selenium import webdriver from selenium.webdriver.chrome.service import Service from selenium.webdriver.chrome.options import Options from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.action_chains import ActionChains import PySimpleGUI as sg from pathlib import Path import pandas as pd url = r"https://simpletire.com/brands/american-tourer-tires/touring-a-s#badge=Best%20rated&curationPos=none&curationSeq=none&curationSource=none&delivery=Del3&itemId=208786&mpn=AMSYTH0258&pageSource=PDP&pick=best-rated&productPos=none&rad=BE&region=r2&tireSize=195-55r15&userRegion=2&userZip=19422&v=1&zip=19422" service = r"somefilepath" filename = "simple_tire_data" def extract_data(url, service, output_folder, filename): """Main function for extracting data from simpletire.com and exporting to excel. Parameters: url -- the url of the page with the drop-down list of tire options service -- the absolute folder path to your chromedriver.exe on your PC. Please ensure you have the version downloaded that matches your chrome web browser version. You can download the chromedriver.exe from this site: https://chromedriver.chromium.org/downloads output_folder -- the folder where you want to store the output excel file filename -- the name of the output excel file """ # use selenium to open URL with chrome driver driver = get_driver(url, service) # wait for pop-up to appear WebDriverWait(driver, 30).until(EC.presence_of_element_located((By.XPATH, "//*[@id='attentive_overlay']"))) # find and click "X" button to close pop-up try: close_button = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.TAG_NAME, "button"))) actions = ActionChains(driver) actions.move_to_element(close_button).click().perform() except: print("Pop up message was not able to be dismissed.") # find the dropdown list and loop through the options dropdown = driver.find_element(By.XPATH, "//*[@id='selectSizeButton']") options = dropdown.find_elements(By.TAG_NAME, "span") tire_data = {} # for option in options: # option_text = option.text # option.click() # # get data from tech specs container # tech_specs_data = scrape_tech_specs_data(driver) # # store data in nested dictionary # tire_data[option_text] = tech_specs_data # print(tire_data) # driver.quit() # # convert dictionary to dataframe # df = pd.DataFrame.from_dict(tire_data, orient="index") # # export dataframe to excel # output_path = Path(output_folder, f"{filename}.xlsx") # df.to_excel(output_path, index=True) def get_driver(url, service): chrome_options = Options() chrome_options.add_experimental_option("detach", True) service = Service(rf"{service}") chrome_browser = webdriver.Chrome(service=service, options=chrome_options) chrome_browser.get(rf"{url}") chrome_browser.maximize_window() return chrome_browser extract_data(url, service, output_folder, filename)
弹窗的HTML结构截图:
解决方案
核心问题分析
当前代码用By.TAG_NAME定位button时,会匹配页面上第一个可点击的按钮,而非弹窗内的关闭按钮;同时仅等待弹窗元素“存在”,而非“完全可见可交互”,导致弹窗未渲染完成时就执行点击操作,最终触发错误按钮。
具体修复步骤
精准定位弹窗内的关闭按钮
根据HTML截图,弹窗容器ID为attentive_overlay,关闭按钮是该容器内的button元素,通过XPATH限定范围,确保只定位弹窗内的按钮:# 优先匹配弹窗内带关闭类名的按钮 close_button = WebDriverWait(driver, 20).until( EC.element_to_be_clickable((By.XPATH, "//div[@id='attentive_overlay']//button[contains(@class, 'attentive_close')]")) )如果按钮带有
aria-label="Close"这类属性,也可以用更精准的定位:close_button = WebDriverWait(driver, 20).until( EC.element_to_be_clickable((By.XPATH, "//div[@id='attentive_overlay']//button[@aria-label='Close']")) )等待弹窗完全可见
将原来等待弹窗“存在”的逻辑,改为等待弹窗“可见”,确保弹窗完全渲染后再操作:# 替换presence_of_element_located为visibility_of_element_located WebDriverWait(driver, 30).until(EC.visibility_of_element_located((By.XPATH, "//*[@id='attentive_overlay']")))简化点击操作
当元素已被判定为可点击时,无需使用ActionChains,直接调用click()更可靠:close_button.click()
修复后的完整弹窗处理代码
# 等待弹窗完全可见 WebDriverWait(driver, 30).until(EC.visibility_of_element_located((By.XPATH, "//*[@id='attentive_overlay']"))) # 找到并关闭弹窗 try: # 精准定位弹窗内的关闭按钮 close_button = WebDriverWait(driver, 20).until( EC.element_to_be_clickable((By.XPATH, "//div[@id='attentive_overlay']//button[contains(@class, 'attentive_close')]")) ) close_button.click() print("弹窗已成功关闭") except: print("无法关闭弹窗")
额外调试技巧
- 如果弹窗嵌套在
iframe内,需先切换到iframe再定位元素:WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.ID, "attentive_frame"))) # 定位关闭按钮... # 操作完成后切回主文档 driver.switch_to.default_content() - 可通过
driver.page_source打印当前页面源码,确认弹窗元素是否加载,排查定位失败原因。
内容的提问来源于stack exchange,提问作者Kevin Agbulos
相关产品推荐
相关产品推荐

