4

我正在尝试选择一个下拉菜单并选择一个选项。我正在使用最新版本的 Selenium、最新版本的 Firefox、最新版本的 geckodriver 和最新版本的 Python。

这是我的问题:当我尝试选择一个选项时,它给了我以下错误:

selenium.common.exceptions.ElementNotInteractableException: Message: Element <option> could not be scrolled into view.

我尝试了各种方法来解决这个问题,但似乎都没有奏效。以下是我尝试过的一些方法。

mySelectElement = browser.find_element_by_id('providerTypeDropDown')
dropDownMenu = Select(mySelectElement)
dropDownMenu.select_by_visible_text('Professional')

mySelectElement = browser.find_element_by_id('providerTypeDropDown')
dropDown = Select(mySelectElement)
for option in dropDown.options:
    message = option.get_attribute('innerText')
    print(message)
    if message == 'Professional':
        print("Exists")
        dropDown.select_by_visible_text(message) 
        break

element = browser.find_element_by_id('providerTypeDropDown')
browser.execute_script("var select = arguments[0]; for(var i = 0; i < select.options.length; i++){ if(select.options[i].text == arguments[1]){ select.options[i].selected = true; } }", element, "Professional")

HTML 代码遵循通常的选择标签和选项标签。任何帮助表示赞赏。HTML 代码包含在下面。

<select data-av-chosen="providerTypes" id="providerTypeDropDown" data-placeholder="Please Select a Provider Type" name="providerTypeDropDown"
class="chzn-select input-full ng-pristine chzn-done ng-invalid ng-invalid-provider-type" data-ng-options="providerType.value for providerType in request.models.providerTypes"
data-ng-model="request.models.providerType" data-av-validator-field="providerType" data-disable-search-threshold="5" style="display; none;">
    <option value="" class="">Please Select a Provider Type</option>
    <option value="0">Professional</option>
    <option value="1">Institutional</option>
</select> 

打印语句用于测试/代码跟踪。

4

3 回答 3

4

此错误消息...

selenium.common.exceptions.ElementNotInteractableException: Message: Element <option> could not be scrolled into view.

...意味着<option>您的程序试图与之交互的项目无法滚动到视图中。

所需元素的HTML会给我们一些错误背后的想法。但是,似乎所需的元素不在Viewportclickable之内。要解决该问题,您必须诱导WebDriverWait元素可点击,您可以使用以下解决方案:

mySelectElement = browser.find_element_by_id('providerTypeDropDown')
dropDownMenu = Select(mySelectElement)
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//select[@id='providerTypeDropDown']//options[contains(.,'Professional')]")))
dropDownMenu.select_by_visible_text('Professional')

注意:您必须添加以下导入:

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.select import Select
于 2018-07-09T18:46:26.680 回答
2

尝试添加等待:

mySelectElement = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, "providerTypeDropDown")))
mySelectElement.click()

它将等待至少 10 秒,直到元素可以单击,然后单击。

此外,我在您的代码中没有看到您单击打开下拉菜单的下拉按钮。找到此按钮,还添加一个等待并单击它,然后再选择该选项。希望能帮助到你。

注意:对于此代码,您必须添加一些导入:

from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
于 2018-07-09T17:48:02.220 回答
0

我有同样的问题。我无法使用 selectByValue、selectByIndex 和 selectByVisible 文本选择下拉值。我也尝试了使用 Javascript 执行器的动作类和滚动。没有任何效果。经过1天的反复试验,我想出了以下解决方法,

public static void selectDropDownByVisibleText(WebElement element, String text){
        waitForPageLoad();
        String firstCharacterDropDownVal = ""+text.charAt(0);
        HashSet<String> uniqueDropDownVals = new HashSet<>();
        try {
            Select select = new Select(element);
            select.selectByVisibleText(text);
        }catch (ElementNotInteractableException e){
            Select select = new Select(element);
            while(!select.getFirstSelectedOption().getText().equalsIgnoreCase(text) &&
                    uniqueDropDownVals.add(select.getFirstSelectedOption().getText())) {
                element.sendKeys(firstCharacterDropDownVal);
            }
        }
        log.info("Selected dropdown by visible text "+text);
    }


public static void waitForPageLoad() {
        log.debug("Waiting for page to get loaded..");
        new WebDriverWait(Driver.getDriver(), Duration.ofSeconds(FIND_ELEMENT_WAIT_TIME)).
                ignoring(NoSuchElementException.class).ignoring(StaleElementReferenceException.class).
                until(webDriver -> ((JavascriptExecutor) webDriver).executeScript("return document.readyState").equals("complete"));
        log.debug("Page loaded successfully");
    }

我将解释工作。首先它将尝试通过可见文本进行选择。如果我们得到异常,它将进入 catch 块内。在那里,我们在下拉 web 元素上发送所需文本的第一个字符。所以下拉元素发生了变化。假设下拉值是 Apple、Aeroplane、Adam,我想选择 Adam。我第一次在 webelement 上发送“A”时,下拉菜单更改为 Apple。然后我将它添加到 HashSet 并检查所选元素是否是所需元素。如果匹配,那么我们就退出 while 循环。如果相同的元素被添加两次,那么 HashSet add 方法将返回 false。这将使我们脱离 while 循环,并防止我们进入无限循环。因此,每次我输入“A”时,下拉值都会更改为以“A”开头的下一个值。

于 2022-03-02T08:20:02.503 回答