Selenium在Flexbox中定位元素失败求助
问题描述
尝试用Selenium访问StubHub页面并点击顶部首个票务列表的按钮,但目标元素嵌套在多层带唯一ID和类名的Flexbox中,使用XPATH、类选择器、CSS选择器均无法定位,代码执行触发超时异常。
页面HTML结构参考截图:
原代码如下:
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.chrome.options import Options from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import espected_conditions as EC url = "https://www.stubhub.com/philadelphia-eagles-philadelphia-tickets-1-21-2023/event/151223773/?quantity=2§ions=195411%2C195410%2C195414%2C195413%2C195409%2C195408%2C195412%2C195415%2C195430%2C195427%2C195432%2C195433%2C195431%2C195428%2C195434%2C195429&ticketClasses=594&listingQty=&multi=true" opt = Options() opt.headless = False driver = webdriver.Chrome('chromedriver.exe', options=opt) driver.maximize_window() driver.get(url) wait = WebDriverWait(driver, 10) wait.until(EC.element_to_be_clickable((By.XPATH, '//*[@id="app"]/div[2]/div/div[2]/div[1]/div/div[2]/div/div/div[1]/div/div/div/div[2]/button'))) driver.find_element(By.XPATH, '//*[@id="app"]/div[2]/div/div[2]/div[1]/div/div[2]/div/div/div[1]/div/div/div/div[2]/button').click()
代码可正常打开浏览器,但等待元素可点击时触发超时异常。
解决方案
1. 修正代码拼写错误
原代码中espected_conditions是拼写错误,正确应为expected_conditions,这会直接导致等待条件无法生效。
2. 处理页面Cookie弹窗
StubHub页面加载后通常会弹出Cookie授权窗口,不处理会遮挡或干扰元素定位,需先点击同意按钮:
# 等待Cookie弹窗并同意 try: wait.until(EC.element_to_be_clickable((By.XPATH, '//button[contains(text(), "Accept")]'))).click() except: pass # 若没有弹窗则跳过
3. 使用相对定位替代绝对XPATH
绝对XPATH依赖页面层级结构,一旦页面布局微调就会失效,改用相对定位,比如根据按钮的文本或更稳定的属性:
# 等待首个票务列表的Buy按钮可点击并点击 target_button = wait.until(EC.element_to_be_clickable((By.XPATH, '(//div[contains(@class, "ticket-listing")]//button[contains(text(), "Buy")])[1]'))) target_button.click()
或者用CSS选择器定位首个符合条件的按钮:
target_button = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, '.ticket-listing button[data-testid="buy-button"]:first-of-type'))) target_button.click()
4. 检查是否存在iframe
如果目标元素嵌套在iframe中,需要先切换到iframe再定位:
# 查找并切换到包含目标元素的iframe iframe = wait.until(EC.presence_of_element_located((By.TAG_NAME, 'iframe'))) driver.switch_to.frame(iframe) # 定位并点击按钮 target_button = wait.until(EC.element_to_be_clickable((By.XPATH, '(//button[contains(text(), "Buy")])[1]'))) target_button.click() # 操作完成后切回主文档 driver.switch_to.default_content()
5. 优化等待策略
适当延长等待时间,或先确认元素存在再等待可点击:
wait = WebDriverWait(driver, 15) # 先等待元素存在 wait.until(EC.presence_of_element_located((By.XPATH, '(//button[contains(text(), "Buy")])[1]'))) # 再等待元素可点击 target_button = wait.until(EC.element_to_be_clickable((By.XPATH, '(//button[contains(text(), "Buy")])[1]'))) target_button.click()
完整修正后的代码
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.chrome.options import Options from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC url = "https://www.stubhub.com/philadelphia-eagles-philadelphia-tickets-1-21-2023/event/151223773/?quantity=2§ions=195411%2C195410%2C195414%2C195413%2C195409%2C195408%2C195412%2C195415%2C195430%2C195427%2C195432%2C195433%2C195431%2C195428%2C195434%2C195429&ticketClasses=594&listingQty=&multi=true" opt = Options() opt.headless = False driver = webdriver.Chrome('chromedriver.exe', options=opt) driver.maximize_window() driver.get(url) wait = WebDriverWait(driver, 15) # 处理Cookie弹窗 try: wait.until(EC.element_to_be_clickable((By.XPATH, '//button[contains(text(), "Accept")]'))).click() except: pass # 定位并点击首个票务列表的Buy按钮 target_button = wait.until(EC.element_to_be_clickable((By.XPATH, '(//div[contains(@class, "ticket-listing")]//button[contains(text(), "Buy")])[1]'))) target_button.click() # 后续操作... # driver.quit()
内容的提问来源于stack exchange,提问作者johne518
相关产品推荐
相关产品推荐

