Я пытаюсь выбрать элемент из неупорядоченного списка, используя 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()






Вы должны иметь возможность выбрать параметр по тексту или его значению:
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.
@RKelley измените свой локатор на "qf_admin_practice_edit__data__status_id", и он должен работать — вы хотите настроить таргетинг на сам элемент <select>.
@TodorMinakov пытался изменить это, и это все еще не работает.
@TodorMinakov Спасибо! Я должен был присмотреться к id. Я взял это из кода, а не из html.
Ваш локатор 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
@BobG: Можете ли вы проверить, находится ли элемент внутри какого-либо iframe?
Это не в iframe. Я обновил фрагмент HTML-кода в основном посте, проверьте его, но не знаю, поможет ли это вообще.
@BobG: просто любопытно, это главная страница или какое-то дочернее окно на главной странице?
Я думаю, что это дочернее окно, но я не совсем уверен, это раскрывающийся список, расположенный на другой странице с еще одним раскрывающимся меню, снимок экрана: i.imgur.com/RVuwMwC.png
Я думаю, вам нужно сначала переключить дочернее окно, тогда мой код будет работать. Вы знаете, как правильно переключить окно?
нет, я не знаю, вы можете объяснить, пожалуйста? если под дочерним окном вы подразумеваете, что оно всплывает в своем собственном отдельном окне и не находится на главной странице, то нет, это главная страница, когда я нажимаю раскрывающееся меню, всплывающее окно не появляется, меню просто отображается, как и ожидалось
Теперь я действительно запутался. HTML-контент, который вы разместили, работает с моим кодом. Однако, если возможно, поделитесь URL-адресом здесь.
К сожалению, я не могу дать ссылку, так как это часть административного портала сайта.
@KunduK Элемент <select>, скорее всего, не виден и не доступен для кликов. Измените условие ожидания на presence_of_element_located, и оно должно работать. @BobG Не могли бы вы попробовать изменить ожидаемое условие - expected_conditions.element_to_be_clickable на expected_conditions.presence_of_element_located?
Желаемый Падать не является тегом <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
Ознакомьтесь с обновленным ответом и дайте мне знать о статусе
Все еще вызывает TimeoutException :(
Есть ли выпадающее меню и открывает его, как я использовал ваш id в форме css_selector и xpath
Да, он открывает раскрывающееся меню, но затем, похоже, не может щелкнуть или выбрать параметр в меню. Скриншот того, куда программа попадает непосредственно перед тем, как выдать эту ошибку: i.imgur.com/sW2KkDQ.png
Я обновил фрагмент HTML-кода в основном посте, не знаю, поможет ли это вам диагностировать это :)
Разобрался, но это уродливое решение, которое мне не нравится, но оно работает.
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)
Это возвращает: UnexpectedTagNameException: Select работает только с элементами <select>, а не с <div>