首页 > 解决方案 > 如何使用 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&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</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&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</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&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</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&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</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&nbsp;ISLAND&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</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

有任何想法吗?

标签: javascriptpythonseleniumdrop-down-menuwebdriverwait

解决方案


要单击带有文本的下拉选项(全选),因为元素是启用了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

推荐阅读