Проверка наличия элемента с помощью Python Selenium
У меня проблема: я использую веб-драйвер selenium (firefox), чтобы открыть веб-страницу, щелкнуть несколько ссылок и т.д., а затем сделать снимок экрана.
My script отлично работает с CLI, но при запуске через cronjob он не проходит первый тест find_element(). Мне нужно добавить отладку или что-то, что поможет мне понять, почему она терпит неудачу.
В принципе, я должен щелкнуть якорь "войти в систему", прежде чем перейти на страницу входа. Конструкция элемента:
<a class="lnk" rel="nofollow" href="/login.jsp?destination=/secure/Dash.jspa">log in</a>
Я использую метод find_element по LINK_TEXT:
login = driver.find_element(By.LINK_TEXT, "log in").click()
Я немного Python Noob, поэтому немного борюсь с языком...
A) Как проверить, действительно ли ссылка набирается python? Должен ли я использовать блок try/catch?
B) Есть ли лучший/более надежный способ найти элемент DOM, чем LINK_TEXT? Например. В JQuery вы можете использовать более специфический селектор $('a.lnk: contains (log in)'). Do_something();
Я решил основную проблему, и это была просто проблема с пальцем - я вызывал script с неправильными параметрами - Простая ошибка.
Мне все еще нравятся некоторые указатели на то, как проверить, существует ли элемент. Кроме того, пример/объяснение неявного/явного ожидания, вместо использования crappy time.sleep().
Приветствия, ns
Ответы
Ответ 1
A) Да. Самый простой способ проверить, существует ли элемент, - просто вызвать find_element
внутри a try/catch
.
B) Да, я всегда пытаюсь идентифицировать элементы без использования их текста по двум причинам:
- текст с большей вероятностью изменится и
- Если это важно для вас, вы не сможете запускать свои тесты против локализованных сборок.
:
- Вы можете использовать xpath для поиска элемента родителя или предка, у которого есть идентификатор или какой-либо другой уникальный идентификатор, а затем найти его дочерний/потоковый, который соответствует или;
- вы можете запросить идентификатор или имя или какой-либо другой уникальный идентификатор самой ссылки.
Для последующих вопросов использование try/catch
заключается в том, как вы можете определить, существует ли элемент или нет, и можно найти хорошие примеры ожиданий: http://seleniumhq.org/docs/04_webdriver_advanced.html
Ответ 2
а)
from selenium.common.exceptions import NoSuchElementException
def check_exists_by_xpath(xpath):
try:
webdriver.find_element_by_xpath(xpath)
except NoSuchElementException:
return False
return True
b) используйте xpath - самый надежный. Кроме того, вы можете использовать xpath как стандарт на всех ваших скриптах и создавать функции, как указано выше, для универсального использования.
ОБНОВЛЕНИЕ. Я написал исходный ответ более 4 лет назад, и в то время, когда я думал, что xpath будет лучшим вариантом. Теперь я рекомендую использовать селекторов CSS. Я по-прежнему рекомендую не смешивать/использовать "по id", "по имени" и т.д. И вместо этого использовать один единственный подход.
Ответ 3
Ни одно из представленных решений не казалось мне самым легким, поэтому я хотел бы добавить свой собственный путь.
В принципе, вы получаете список элементов, а не только элемент, а затем подсчитываете результаты; если он равен нулю, то он не существует. Пример:
if driver.find_elements_by_css_selector('#element'):
print "Element exists"
Обратите внимание на "s" в find_elements_by_css_selector
, чтобы убедиться, что он может быть счетным.
EDIT: я проверял список len(
в списке, но недавно узнал, что пустой список является ложным, так что вам не нужно получать длину списка вообще, оставляя еще более простой код.
Кроме того, в другом ответе говорится, что использование xpath более надежное, что просто неверно. См. В чем разница между css-selector и Xpath? что лучше (в зависимости от производительности и для кросс-браузерного тестирования)?
Ответ 4
Решение без try & catch и без нового импорта:
if len(driver.find_elements_by_id('blah')) > 0: #pay attention: find_element*s*
driver.find_element_by_id('blah').click #pay attention: find_element
Ответ 5
Так же, как Брайан, но добавьте к этому ответу от tstempko:
https://sqa.stackexchange.com/questions/3481/quicker-way-to-assert-that-an-element-does-not-exist
Поэтому я попытался, и он работает быстро:
driver.implicitly_wait(0)
if driver.find_element_by_id("show_reflist"):
driver.find_element_by_id("show_reflist").find_element_by_tag_name("img").click()
после этого я восстанавливаю значение по умолчанию
driver.implicitly_wait(30)
Ответ 6
Вы могли бы также сделать это более
driver.find_element_by_id("some_id").size() != 0
Ответ 7
driver.find_element_by_id("some_id").size()
- метод класса.
Что нам нужно это:
driver.find_element_by_id("some_id").size
словаря так:
if driver.find_element_by_id("some_id").size['width'] != 0: print 'button exist'