javascript - 如何使用 Selenium 和 Python 单击文本为(全选)的下拉项
问题描述
编辑:在此页面上,我正在尝试为要从数据库生成的报告提交参数。我已经能够 send_keys() 与第一个字段的新开始日期。第二个字段(结束日期)保持不变。对于第三个字段,除了一个,我需要点击(Select All)
。
我需要单击(Select All)
,它仅在单击父级“divDropDown”后才会显示在隐藏的下拉表中。激活后,这个隐藏的表格会显示一个 tbody,其中 5-6 tr/td/span 集包含各种选项。您可以在 id 下找到全选选项ctl31_ctl04_ctl07_divDropDown_ctl00
。
在 HTML 的更深处,有一个 dropDownButton 不会在代码中生成错误(前 2 行),但也不会在浏览器上显示为像手动那样激活该下拉菜单,所以我认为它没有帮助这里。
我已经搜索了相关答案并尝试了 Selenium 中的各种代码(等待、execute_script 等)来访问这个项目,甚至尝试切换到它上面的 iframe(即使点击输入区域时它似乎也会激活)寻找的元素在它之外),但仍然出现错误“无法找到元素......”这里有各种代码尝试:
driver.find_element_by_xpath('//*[@id="ctl31_ctl04_ctl07"]')#.click()
driver.find_element_by_xpath('//*[@id="ctl31_ctl04_ctl07_ddDropDownButton"]').click()
#driver.find_element_by_xpath('//*[@id="ctl31_ctl04_ctl07_divDropDown"]').click()
#driver.execute_script("event.cancelBubble=true;")
#driver.execute_script("arguments[0].click();", elem)
#driver.find_element_by_xpath('//*[@id="ctl31_ctl04_ctl07_divDropDown_HiddenIndices" and @type="hidden"]')
#elem1 = driver.find_element_by_xpath('//*[@id="ctl31_ctl04_ctl07_divDropDown_ctl00" and @type="checkbox"]')#.click()
elem1 = driver.find_element_by_xpath('//*div[@id="ctl31_ctl04_ctl07_divDropDown"]/.//span[@id="ctl31_ctl04_ctl07_divDropDown_ctl00"]').get_attribute("innerHTML")
driver.execute_script("arguments[0].click();", elem1)
selector = '#ctl31_ctl04_ctl07_divDropDown_ctl00'
selector = '#ctl31_ctl04_ctl07_divDropDown > span > div:nth-child(1) > table > tbody > tr:nth-child(1) > td > span > label'
path = '//*[@id="ctl31_ctl04_ctl07_divDropDown"]/span/div[1]/table/tbody/tr[1]/td/span/input'#label'
#path = '//*[@id="ctl31_ctl04_ctl07_divDropDown_ctl00"]'
#driver.find_element_by_css_selector(selector).click()
driver.find_element_by_xpath(path).click()
我相信它无法找到元素,因为它通常是隐藏的,但是无论我如何尝试单击或执行下拉菜单,通过按钮或单击 div,它都不会保持打开状态(我确实看到它有时会闪烁,它只是重新关闭,因此表格和它的下拉菜单再次隐藏)。我也试过下面的代码来测试它。使用常规的等待命令,我会在一些迭代后得到“陈旧元素”错误。没有任何等待,我会找不到元素。使用“等到”,我可以看到下拉菜单向上/向下移动,但在可见时似乎无法捕捉到“全选”?所有这一切都是用我的打印语句打开/关闭下拉列表以查看何时(在打印“检查是否存在”之后)。我也试过直接执行'全选'"$get('ctl31_ctl04_ctl07').control.OnSelectAllClick(this);"
def check_exists_by_xpath(xpath):
try:
driver.find_element_by_xpath(xpath)
except NoSuchElementException:
return False
return True
for i in range(15):
#driver.implicitly_wait(1000)
#driver.find_element_by_xpath('//*[@id="ctl31_ctl04_ctl07_ddDropDownButton"]').click()
wait(driver, 1000).until(EC.element_to_be_clickable((By.XPATH, '//*[@id="ctl31_ctl04_ctl07_ddDropDownButton"]'))).click()
#elem = driver.find_element_by_xpath('//*[@id="ctl31_ctl04_ctl07_divDropDown_ctl00"]')
print('checking if exists')
if check_exists_by_xpath('//*[@id="ctl31_ctl04_ctl07_divDropDown_ctl00"]'):
driver.find_element_by_xpath('//*[@id="ctl31_ctl04_ctl07_divDropDown_ctl00"]').click()
print('did it!')
else: print('past dropdown button %d' % i)
i +=1
这是 HTML(这是一个登录网站,所以我无法显示其他内容,抱歉图片:html
<iframe id="ctl31_ctl04_ctl07_ctl01" onclick="event.cancelBubble=true;" onactivate="event.cancelBubble=true;" style="display:none;position:absolute;z-index:10;" src="javascript:'';" frameBorder="0" title="Borough: place holder" longdesc="Borough: place holder" Name="ctl31_ctl04_ctl07_ctl01"></iframe>
<div id="ctl31_ctl04_ctl07_divDropDown" onclick="event.cancelBubble=true;" onactivate="event.cancelBubble=true;" style="display:inline-block;border-color:DarkGray;border-width:1px;border-style:Solid;overflow:auto;background-color:window;display:none;position:absolute;z-index:11;">
<span style="margin: 0px; background-color: window;"><div style="overflow: auto; width: 186px; height: 133px;">
<table cellpadding="0" cellspacing="0" style="background-color:window;">
<tbody>
<tr>
<td nowrap="nowrap">
<span>
<input id="ctl31_ctl04_ctl07_divDropDown_ctl00" type="checkbox" name="ctl31$ctl04$ctl07$divDropDown$ctl00" onclick="$get('ctl31_ctl04_ctl07').control.OnSelectAllClick(this);"><label for="ctl31_ctl04_ctl07_divDropDown_ctl00">(Select All)</label>
</span></td></tr>
<tr>
<td nowrap="nowrap"><span><input id="ctl31_ctl04_ctl07_divDropDown_ctl01" type="checkbox" name="ctl31$ctl04$ctl07$divDropDown$ctl01" onclick="$get('ctl31_ctl04_ctl07').control.OnValidValueClick(this, 'ctl31_ctl04_ctl07_divDropDown_ctl00');"><label for="ctl31_ctl04_ctl07_divDropDown_ctl01">MANHATTAN </label></span></td></tr>
<tr>
<td nowrap="nowrap"><span><input id="ctl31_ctl04_ctl07_divDropDown_ctl02" type="checkbox" name="ctl31$ctl04$ctl07$divDropDown$ctl02" onclick="$get('ctl31_ctl04_ctl07').control.OnValidValueClick(this, 'ctl31_ctl04_ctl07_divDropDown_ctl00');"><label for="ctl31_ctl04_ctl07_divDropDown_ctl02">BROOKLYN </label></span></td></tr>
<tr>
<td nowrap="nowrap"><span><input id="ctl31_ctl04_ctl07_divDropDown_ctl03" type="checkbox" name="ctl31$ctl04$ctl07$divDropDown$ctl03" onclick="$get('ctl31_ctl04_ctl07').control.OnValidValueClick(this, 'ctl31_ctl04_ctl07_divDropDown_ctl00');"><label for="ctl31_ctl04_ctl07_divDropDown_ctl03">QUEENS </label></span></td></tr>
<tr>
<td nowrap="nowrap"><span><input id="ctl31_ctl04_ctl07_divDropDown_ctl04" type="checkbox" name="ctl31$ctl04$ctl07$divDropDown$ctl04" onclick="$get('ctl31_ctl04_ctl07').control.OnValidValueClick(this, 'ctl31_ctl04_ctl07_divDropDown_ctl00');"><label for="ctl31_ctl04_ctl07_divDropDown_ctl04">BRONX </label></span></td></tr>
<tr>
<td nowrap="nowrap"><span><input id="ctl31_ctl04_ctl07_divDropDown_ctl05" type="checkbox" name="ctl31$ctl04$ctl07$divDropDown$ctl05" onclick="$get('ctl31_ctl04_ctl07').control.OnValidValueClick(this, 'ctl31_ctl04_ctl07_divDropDown_ctl00');"><label for="ctl31_ctl04_ctl07_divDropDown_ctl05">STATEN ISLAND </label></span></td></tr>
</tbody>
</table>
<input type="hidden" name="ctl31$ctl04$ctl07$divDropDown$HiddenIndices" id="ctl31_ctl04_ctl07_divDropDown_HiddenIndices" value="">
</div>
<div style="height: 16px; width: 100%; margin: 0px; border-top: 1px solid lightgray; background-color: window; direction: ltr;"></div>
</span>
</div>
以下是网页的外观:page
有任何想法吗?
解决方案
要单击带有文本的下拉选项(全选),因为元素是启用了JavaScript的元素,您需要诱导WebDriverWait以使所需元素可单击,您可以使用以下解决方案:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//div[contains(@id, '_divDropDown') and contains(@onclick, 'cancelBubble')][contains(@onactivate, 'cancelBubble')]"))).click()
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//div[contains(@id, '_divDropDown') and contains(@onclick, 'cancelBubble')][contains(@onactivate, 'cancelBubble')]/span/div/table/tbody/tr/td/span//label[contains(@for, '_divDropDown_') and contains(., '(Select All)')]"))).click()
注意:您必须添加以下导入:
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
推荐阅读
- reporting-services - 当报告项目文本框 =“N/A”时,SSRS 处理 #Error
- docker - Vue JS 2 环境变量在没有端口绑定的情况下连接到 Docker 容器
- docker - Dockerfile rsyslog
- java - 2960x1440 拉伸安卓相机预览
- excel - 不同电子表格的同一单元格的表格列
- java - 如何知道用户是否使用 google 或 facebook 签名按钮 android firebase 登录或注册
- r - 成对获胜者;还是向量值 group_by 变异?
- wordpress - 在 wordpress 页面上渲染一个反应组件
- php - 在 jQuery AJAX 中捕获 PHP 错误正文
- c# - 可以将字符串转换为标签名称吗?