提问人:Quicksilver 提问时间:11/15/2023 更新时间:11/15/2023 访问量:46
无法与 Chrome 中的下拉列表交互
Cannot interact with dropdown in Chrome
问:
这里是 python 的初学者。我想从下拉列表中选择一个选项。我一直得到“元素不可交互”。我不相信下拉列表上有任何类型的标签覆盖,我可以手动单击下拉列表而不会出现问题。我已经尝试了许多方法,如所示,并在下面出现了相关错误。
这是我的代码:
import selenium
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
#from selenium.webdriver.common.action_chains import action_chains
#from selenium.webdriver.common.actions import Actions
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.select import Select
#from selenium.webdriver.remote import Remote
from selenium.webdriver.chrome.options import Options as ChromeOptions
service = Service()
chrome_options = Options()
chrome_options.add_experimental_option("detach", True)
driver = webdriver.Chrome(service=service, options=chrome_options)
driver.get("https://gtc.clubautomation.com/")
#
#
# removed code to login and move to reservations page
#
#
reserve_court_link = driver.find_element(by=By.ID, value="menu_reserve_a_court")
reserve_court_link.click()
driver.maximize_window()
driver.refresh()
driver.execute_script("window.scrollTo(0,600)")
#Choose service (unecessary manually, but hopefully driving further options?? Only one option to pick)
service_dropdown = Select(driver.find_element(by=By.XPATH, value="//select[@id='component'][@name='component']"))
service_dropdown.select_by_value("2")
#Choose pickleball option
pickleball_dropdown = Select(driver.find_element(by=By.XPATH, value="//select[@id='location'][@name='location']"))
dropdown_element = driver.find_element(by=By.XPATH, value="//select[@id='location'][@name='location']")
#Verify dropdown exists
if pickleball_dropdown is not None:
print("drop down exists")
else:
print("dropdown does NOT exist")
#Verify I have the right dropdown
test_option = pickleball_dropdown.first_selected_option
print(test_option.get_attribute("innerHTML"))
#print values of dropdown
for opt in pickleball_dropdown.options:
print("option: " + opt.get_attribute("innerHTML") + " : " + opt.get_attribute("value"))
#select by visible text doesn't seem to do anything.
pickleball_dropdown.select_by_visible_text("All Service Locations")
# expand housing type dropdown using javascript -- doesn't seem to actually expand dropdown
dropdown_trigger = driver.find_element(by=By.XPATH, value="//select[@id='location'][@name='location']")
driver.execute_script("arguments[0].click();", dropdown_trigger)
#Wait for object to be clickable -- times out.
#WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//select[@id='location'][@name='location']"))).click()
#error: ElementNotInteractableException: Message: element not interactable
dropdown_element.click()
#AttributeError: 'Select' object has no attribute 'click'
#pickleball_dropdown.click()
#ElementNotInteractableException: Message: element not interactable: Element is not currently visible and may not be manipulated
pickleball_dropdown.select_by_value("35")
我包含了要与之交互的页面的屏幕截图和 HTML
<div class="reserve-court-new-header">Make a New Reservation</div>
<div class="reserve-court-new">
<div class="ca-element-error-wrapper">
<input type="hidden" name="user_id" value="37688" id="user_id">
</div>
<div class="ca-element-error-wrapper">
<input type="hidden" name="event_member_token_reserve_court" value="b3f10b9d113922226d18db05b8c3a448" id="event_member_token_reserve_court">
</div>
<div class="ca-element-error-wrapper">
<input type="hidden" name="current_guest_count" value="0" id="current_guest_count">
</div>
<div class="r-line">
<div class="t-block">What Service?</div>
<div class="i-block"><div class="ca-element-error-wrapper">
<span class="ca-pro-ui"><span class="select-input-container">
<select name="component" id="component" class="ca-select">
<option value="2" selected="selected">Tennis</option>
</select>
<script type="text/javascript">
(function($) {
$(document).ready(function() {
$("#component").caSelect({"width":150,"tickWidth":30,"selectType":"select"});
});
})(jQuery)
</script>
</span>
</span>
</div>
</div>
<div class="clear-both"></div>
</div>
<div class="r-line" >
<div class="t-block">Where?</div>
<div class="i-block" style="display: none;">
<div class="ca-element-error-wrapper">
<span class="ca-pro-ui"><span class="select-input-container">
<select name="club" id="club" class="ca-select">
<option value="-1" selected="selected">All Locations</option>
<option value="1">Lifetime Tennis GTC</option>
</select>
<script type="text/javascript">
(function($) {
$(document).ready(function() {
$("#club").caSelect({"width":150,"tickWidth":30,"selectType":"select"});
});
})(jQuery)
</script>
</span>
</span>
</div>
</div>
<div class="i-block"><div class="ca-element-error-wrapper">
<span class="ca-pro-ui"><span class="select-input-container">
<select name="location" id="location" class="ca-select">
<option value="-1">All Service Locations</option>
<option value="1">Tennis</option>
<option value="35">Pickleball / Mini Tennis</option>
</select>
答:
1赞
touero
11/15/2023
#1
我使用硒已经有一段时间了,大多数情况下我很少使用Select,我认为它不是很不确定。我省略了一些代码。我希望你能理解它。所以我的经验如下:
from selenium.webdriver.support import expected_conditions as ec
from selenium.webdriver.support.wait import WebDriverWait
driver = Chrome()
单击此选项可显示下拉框“将此下拉框视为具有多行和多列的表”。
准备逐行遍历此表,如下所示
rows = WebDriverWait(driver, timeout).until(ec.presence_of_all_elements_located((By.XPATH, xpath)))
或
rows = driver.find_elements(By.XPATH, xpath)
上面的代码 xpath 是这个下拉框的每一行,所以它返回一个 List[WebElement]
- 现在我们需要遍历表,如果这个元素符合你的条件,请使用它。以下是选择性别的示例。
for row in rows: temp = row.find_element(By.XPATH,'.//option') if 'male' in temp.text: temp.click() break ...
在 Selenium 4.11 中......
评论
0赞
Quicksilver
11/29/2023
谢谢你的回答!rows 对象被填充,但它似乎没有从“.//option”中找到任何选项。我使用 Select 对象和 Options 方法的方法确实返回了三个可见选项的文本。你知道为什么会这样吗?
1赞
touero
11/29/2023
@Quicksilver,我认为这也不是真正的 Select,我已经使用 selenium 很长时间了,Select 很少使用,因为它不稳定。我不知道你这么说,但它似乎没有从“.//选项”中找到任何选项。这里xpath通过做你想做的事来写,基于以上我简单的猜测是,然后逐个评估属性值进行选择: ,在进行这些操作之前首先确保出现下拉框。eles = driver.find_elements(By.XPATH, '//select [@id="club"]/option')
for ele in eles: if ele.get_attribute('value')=='1': ele.click()
评论
<div>