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

Selenium自动化测试:列表元素无法交互问题求助

Selenium自动化测试:类别/子类别选择时的“元素不可交互”问题排查

问题描述

我编写了一段Selenium自动化测试代码,用于在Tunai商家系统中完成登录及服务信息录入操作,但在尝试从列表中选择类别/子类别元素时,系统提示“元素不可交互”错误。已尝试使用click()方法及driver.implicitly_wait(),但问题仍未解决,恳请帮忙排查。

测试代码

from selenium import webdriver  
import time  
from selenium.webdriver.common.keys import Keys  
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support.ui import Select
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.remote.webelement import WebElement

driver = webdriver.Chrome('chromedriver')
driver.get('https://devbusiness.tunai.io/login')
time.sleep(2)
driver.maximize_window()

# 输入登录凭证
username = driver.find_element(By.NAME, "loginUsername");
username.send_keys("kevin@tunai");

password = driver.find_element(By.NAME, "loginPassword");
password.send_keys("xxxxx");

login = driver.find_element(By.XPATH,"//*[@id='app']/div/div/div/div/div/div[2]/form/div[4]/button");
login.submit();
time.sleep(2)

# 等待登录完成
WebDriverWait(driver=driver, timeout=10).until(
    lambda x: x.execute_script("return document.readyState === 'complete'")
)
# 验证登录是否成功
error_message = "Incorrect username or password."
errors = driver.find_elements(By.CLASS_NAME, "flash-error")

if any(error_message in e.text for e in errors): 
    print("[!] Login failed")
else:
    print("[+] Login successful")

driver.get("https://devbusiness.tunai.io/dashboard/salon_menu_service")

service = driver.find_element(By.XPATH,"//*[@id='page-content']/div/div[2]/div[1]/div[1]/button")
service.click();
driver.find_element(By.TAG_NAME,"input").send_keys("Hair Dying")

price = driver.find_element(By.XPATH,"//*[@id='page-content']/div/div[2]/div[1]/div[1]/div/div[2]/div/div/form/div[1]/div[1]/div/div[1]/div[2]/div[1]/div/div/input")
price.clear()
price.send_keys("50")

baseprice = driver.find_element(By.XPATH,"//*[@id='page-content']/div/div[2]/div[1]/div[1]/div/div[2]/div/div/form/div[1]/div[1]/div/div[1]/div[2]/div[2]/div/div/input")
baseprice.clear()
baseprice.send_keys("10")

# 类别按钮
category_button = driver.find_element(By.XPATH,"//*[@id='page-content']/div/div[2]/div[1]/div[1]/div/div[2]/div/div/form/div[1]/div[1]/div/div[1]/div[3]/div/div/div/div[2]")
# 类别选项:Category 2 - BeautyPOS
category_select = driver.find_element(By.XPATH,"""//*[@id="page-content"]/div/div[2]/div[1]/div[1]/div/div[2]/div/div/form/div[1]/div[1]/div/div[1]/div[3]/div/div/div/div[3]/ul/li[2]/span""")

category_button.click()
category_select.click()
time.sleep(3)

# 子类别按钮
subcategory_button = driver.find_element(By.XPATH,"//*[@id='page-content']/div/div[2]/div[1]/div[1]/div/div[2]/div/div/form/div[1]/div[1]/div/div[1]/div[4]/div/div/div/div[3]")
# 子类别选项:Category 4 - HairCut
subcategory_select = driver.find_element(By.XPATH,"""//*[@id="page-content"]/div/div[2]/div[1]/div[1]/div/div[2]/div/div/form/div[1]/div[1]/div/div[1]/div[4]/div/div/div/div[3]/ul/li[2]""")

subcategory_button.click()
subcategory_select.click()
time.sleep(3)

解决办法

针对“元素不可交互”问题,可从以下几个方向排查修复:

1. 替换强制等待为显式等待

不要依赖time.sleep(),改用WebDriverWait等待元素处于可点击状态,确保元素完全加载完成后再操作:

from selenium.webdriver.support import expected_conditions as EC

# 处理类别选择
category_button = WebDriverWait(driver, 10).until(
    EC.element_to_be_clickable((By.XPATH, "//*[@id='page-content']/div/div[2]/div[1]/div[1]/div/div[2]/div/div/form/div[1]/div[1]/div/div[1]/div[3]/div/div/div/div[2]"))
)
category_button.click()

# 等待类别选项可点击
category_select = WebDriverWait(driver, 10).until(
    EC.element_to_be_clickable((By.XPATH, "//*[@id='page-content']/div/div[2]/div[1]/div[1]/div/div[2]/div/div/form/div[1]/div[1]/div/div[1]/div[3]/div/div/div/div[3]/ul/li[2]/span"))
)
category_select.click()

# 子类别同理
subcategory_button = WebDriverWait(driver, 10).until(
    EC.element_to_be_clickable((By.XPATH, "//*[@id='page-content']/div/div[2]/div[1]/div[1]/div/div[2]/div/div/form/div[1]/div[1]/div/div[1]/div[4]/div/div/div/div[3]"))
)
subcategory_button.click()

subcategory_select = WebDriverWait(driver, 10).until(
    EC.element_to_be_clickable((By.XPATH, "//*[@id='page-content']/div/div[2]/div[1]/div[1]/div/div[2]/div/div/form/div[1]/div[1]/div/div[1]/div[4]/div/div/div/div[3]/ul/li[2]"))
)
subcategory_select.click()

2. 解决元素被遮挡问题

如果元素被弹窗、浮层遮挡,可尝试两种方式触发点击:

  • ActionChains模拟鼠标操作:
    ActionChains(driver).move_to_element(category_select).click().perform()
    
  • 执行JavaScript直接点击:
    driver.execute_script("arguments[0].click();", category_select)
    

3. 优化元素定位策略

避免使用冗长的绝对XPATH,改用相对定位提升稳定性,比如结合元素文本或属性:

# 定位类别按钮(假设按钮包含“选择类别”文本)
category_button = driver.find_element(By.XPATH, "//div[contains(@class, 'select-trigger') and contains(text(), '选择类别')]")
# 定位类别选项(通过文本匹配)
category_select = driver.find_element(By.XPATH, "//ul[@class='select-dropdown-list']/li/span[text()='Category 2 - BeautyPOS']")

4. 实现随机选择类别/子类别

如果需要随机选择,先获取所有可用选项,再随机挑选:

import random

# 点击类别按钮后,等待所有选项加载
category_options = WebDriverWait(driver, 10).until(
    EC.presence_of_all_elements_located((By.XPATH, "//*[@id='page-content']/div/div[2]/div[1]/div[1]/div/div[2]/div/div/form/div[1]/div[1]/div/div[1]/div[3]/div/div/div/div[3]/ul/li"))
)
# 随机选择一个选项
random.choice(category_options).click()

内容的提问来源于stack exchange,提问作者Carl Carl

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 21:20:30