Выбор элемента из выпадающего меню списка с использованием Python + Selenium

Я пытаюсь выбрать элемент из неупорядоченного списка, используя Selenium в Python. Мой текущий код щелкает раскрывающееся меню и открывает его, но мне не удается заставить его щелкнуть элемент в списке.

Я пытаюсь заставить его нажать «Неактивно».

Вот фрагмент HTML:

<form method = "post" action = "/user/admin/user/practice/edit/18" id = "qf_admin_practice_edit" class = "qf-form"
      onsubmit = "return validate(this)">
    <fieldset id = "qf_admin_practice_edit__data" class = "qf-fieldset">
        <legend>Edit Practice</legend>
        <div class = "qf-select-wrapper" id = "qf_admin_practice_edit__data__status_id__wrapper">
        <span class = "qf-label-span" id = "qf_admin_practice_edit__data__status_id__label_span">
            <label id = "qf_admin_practice_edit__data__status_id__label" for = "qf_admin_practice_edit__data__status_id">Practice Status</label>
        </span>
            <span class = "qf-select-span" id = "qf_admin_practice_edit__data__status_id__span">
            <span class = "qf-select-inner" id = "qf_admin_practice_edit__data__status_id__inner">
                <div class = "selectric-wrapper selectric-qf-select selectric-above selectric-open">
                    <div class = "selectric-hide-select">
                <select title = "Practice Status" name = "admin_practice_edit__data__status_id"
                        id = "qf_admin_practice_edit__data__status_id" class = "qf-select" tabindex = "-1">
                    <option value = "1" class = "qf-option">Active</option>
                    <option value = "2" class = "qf-option">Inactive</option>
                    <option value = "3" class = "qf-option">Pending</option>
                    <option value = "4" class = "qf-option">Billing Suspension</option>
                    <option value = "5" class = "qf-option">Activity Suspension</option>
                    <option value = "6" class = "qf-option">Declined</option>
                    <option value = "7" selected = "selected" class = "qf-option">Deleted</option>
                    <option value = "8" class = "qf-option">Cancelled</option>
                    <option value = "9" class = "qf-option">Reschedule</option>
                    <option value = "10" class = "qf-option">Expired</option>
                    <option value = "11" class = "qf-option">New</option>
                </select>
                    </div>
                    <div class = "selectric">
                    <span class = "label">Deleted</span>
                        <b class = "button">▾</b>
                </div>
                    <div class = "selectric-items" tabindex = "-1" style = "width: 718px; height: 300px;">
                        <div class = "selectric-scroll">
                            <ul>
                                <li data-index = "0" class = "qf-option">Active</li>
                                <li data-index = "1" class = "qf-option">Inactive</li>
                                <li data-index = "2" class = "qf-option">Pending</li>
                                <li data-index = "3" class = "qf-option">Billing Suspension</li>
                                <li data-index = "4" class = "qf-option">Activity Suspension</li>
                                <li data-index = "5" class = "qf-option">Declined</li>
                                <li data-index = "6" class = "qf-option selected highlighted">Deleted</li>
                                <li data-index = "7" class = "qf-option">Cancelled</li>
                                <li data-index = "8" class = "qf-option">Reschedule</li>
                                <li data-index = "9" class = "qf-option">Expired</li>
                                <li data-index = "10" class = "qf-option last">New</li>
                            </ul>
                        </div>
                    </div>
                    <input class = "selectric-input" tabindex = "0">
                </div>
        </span>
      </span>
        </div>
    </fieldset>
    <div class = "qf-button-wrapper" id = "qf_admin_practice_edit__submit__wrapper">
        <button type = "submit" value = "Submit" id = "qf_admin_practice_edit__submit" class = "qf-button">
            <span>Submit</span>
        </button>
    </div>
    <div>
        <input value = "2449978437" type = "hidden" name = "qf" class = "qf-hidden-input qf-input">
    </div>
</form>

Я выбираю/открываю раскрывающееся меню, используя:

clickDropDown = driver.find_element_by_id('qf_admin_practice_edit__data__status_id__wrapper').click()
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
0
2 749
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Вы должны иметь возможность выбрать параметр по тексту или его значению:

dropDown = Select(driver.find_element_by_id("admin_practice_edit__data__status_id"))
dropDown.click()
# Select by text
dropDown.select_by_visible_text("Inactive")
# or by value
dropDown.select_by_value('2')

Дополнительную информацию о работе с раскрывающимися списками можно найти здесь: https://seleniumhq.github.io/selenium/docs/api/py/webdriver_support/selenium.webdriver.support.select.html.

Это возвращает: UnexpectedTagNameException: Select работает только с элементами <select>, а не с <div>

Bob G 18.04.2019 04:05

@RKelley измените свой локатор на "qf_admin_practice_edit__data__status_id", и он должен работать — вы хотите настроить таргетинг на сам элемент <select>.

Todor Minakov 18.04.2019 07:57

@TodorMinakov пытался изменить это, и это все еще не работает.

Bob G 18.04.2019 15:59

@TodorMinakov Спасибо! Я должен был присмотреться к id. Я взял это из кода, а не из html.

RKelley 18.04.2019 19:18

Ваш локатор ID неправильно идентифицирует элемент Select. Однако для выбора элемента не обязательно нажимать на элемент. Вы можете сначала назначить выбранный элемент с помощью локатора, а затем использовать следующий метод для доступа к элементу.

element.select_by_visible_text("text")
element.select_by_index(index number)
element.select_by_value("option value")

Однако лучше всего использовать WebDriverWait при доступе к любой веб-странице. Я предоставил код, надеюсь, это поможет.

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions
from selenium import webdriver
from selenium.webdriver.support.select import Select

driver=webdriver.Chrome()
driver.get("url here")
dropdownelement=WebDriverWait(driver,20).until(expected_conditions.element_to_be_clickable((By.ID,'qf_admin_practice_edit__data__status_id')))
select=Select(dropdownelement)
select.select_by_visible_text("Inactive")

ИЛИ

select.select_by_index(1)

ИЛИ

select.select_by_value("2")

Спасибо! Но это вызывает ошибку TimeoutException: raise TimeoutException(message, screen, stacktrace) TimeoutException

Bob G 18.04.2019 15:23

@BobG: Можете ли вы проверить, находится ли элемент внутри какого-либо iframe?

KunduK 18.04.2019 15:53

Это не в iframe. Я обновил фрагмент HTML-кода в основном посте, проверьте его, но не знаю, поможет ли это вообще.

Bob G 18.04.2019 16:00

@BobG: просто любопытно, это главная страница или какое-то дочернее окно на главной странице?

KunduK 18.04.2019 16:10

Я думаю, что это дочернее окно, но я не совсем уверен, это раскрывающийся список, расположенный на другой странице с еще одним раскрывающимся меню, снимок экрана: i.imgur.com/RVuwMwC.png

Bob G 18.04.2019 16:19

Я думаю, вам нужно сначала переключить дочернее окно, тогда мой код будет работать. Вы знаете, как правильно переключить окно?

KunduK 18.04.2019 16:24

нет, я не знаю, вы можете объяснить, пожалуйста? если под дочерним окном вы подразумеваете, что оно всплывает в своем собственном отдельном окне и не находится на главной странице, то нет, это главная страница, когда я нажимаю раскрывающееся меню, всплывающее окно не появляется, меню просто отображается, как и ожидалось

Bob G 18.04.2019 16:51

Теперь я действительно запутался. HTML-контент, который вы разместили, работает с моим кодом. Однако, если возможно, поделитесь URL-адресом здесь.

KunduK 18.04.2019 17:15

К сожалению, я не могу дать ссылку, так как это часть административного портала сайта.

Bob G 18.04.2019 17:44

@KunduK Элемент <select>, скорее всего, не виден и не доступен для кликов. Измените условие ожидания на presence_of_element_located, и оно должно работать. @BobG Не могли бы вы попробовать изменить ожидаемое условие - expected_conditions.element_to_be_clickable на expected_conditions.presence_of_element_located?

S Ahmed 18.04.2019 21:44

Желаемый Падать не является тегом <select>, поскольку он имеет classатрибут как selectric-скрыть-выбрать. Чтобы click() на элементе с текстом как Активный из Падать, используя Селен через питон, вам нужно вызвать WebDriverWait, и вы можете использовать любой из следующих Стратегии поиска:

  • Использование CSS_SELECTOR:

    driver.find_element_by_css_selector("div.qf-select-wrapper#qf_admin_practice_edit__data__status_id__wrapper").click()
    WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.CSS_SELECTOR, "div.selectric-items>div.selectric-scroll li.qf-option[data-index='0']"))).click()
    
  • Использование XPATH:

    driver.find_element_by_xpath("//div[@class='qf-select-wrapper' and @id='qf_admin_practice_edit__data__status_id__wrapper']").click()
    WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.XPATH, "//div[@class='selectric-items']/div[@class='selectric-scroll']//li[@class='qf-option' and text()='Active']"))).click()
    
  • Примечание: Вы должны добавить следующие импорты:

    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support import expected_conditions as EC
    

Привет, это бросает: поднять TimeoutException (сообщение, экран, трассировка стека) TimeoutException

Bob G 18.04.2019 15:11

Ознакомьтесь с обновленным ответом и дайте мне знать о статусе

undetected Selenium 18.04.2019 15:16

Все еще вызывает TimeoutException :(

Bob G 18.04.2019 15:27

Есть ли выпадающее меню и открывает его, как я использовал ваш id в форме css_selector и xpath

undetected Selenium 18.04.2019 15:29

Да, он открывает раскрывающееся меню, но затем, похоже, не может щелкнуть или выбрать параметр в меню. Скриншот того, куда программа попадает непосредственно перед тем, как выдать эту ошибку: i.imgur.com/sW2KkDQ.png

Bob G 18.04.2019 15:31

Я обновил фрагмент HTML-кода в основном посте, не знаю, поможет ли это вам диагностировать это :)

Bob G 18.04.2019 16:01
Ответ принят как подходящий

Разобрался, но это уродливое решение, которое мне не нравится, но оно работает.

        openDropDown = driver.find_element_by_id('qf_admin_practice_edit__data__status_id__wrapper').click()
        swapToActive = driver.switch_to.active_element
        swapToActive.send_keys(Keys.UP)
        swapToActive.send_keys(Keys.UP)
        swapToActive.send_keys(Keys.UP)
        swapToActive.send_keys(Keys.UP)
        swapToActive.send_keys(Keys.UP)
        swapToActive.send_keys(Keys.RETURN)

Другие вопросы по теме