Проверка наличия элемента с помощью Python Selenium - PullRequest
50 голосов
/ 05 марта 2012

У меня проблема - я использую веб-драйвер selenium (firefox), чтобы открыть веб-страницу, щелкнуть несколько ссылок и т. Д., А затем сделать снимок экрана.

Мой скрипт отлично работает из 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: содержит (войти))'. Do_something ();


Я решил основную проблему, и это была просто проблема с пальцем - я вызывал скрипт с неверными параметрами - Простая ошибка.

Мне все еще хотелось бы узнать, как проверить, существует ли элемент. Кроме того, пример / объяснение неявных / явных Ожиданий вместо использования дрянного вызова time.sleep ().

Ура, нс

Ответы [ 7 ]

78 голосов
/ 28 августа 2012

а)

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 селекторы . Я все еще рекомендую не смешивать / использовать «по идентификатору», «по имени» и т. Д. И использовать вместо этого один единственный подход.

45 голосов
/ 06 марта 2012

А) Да.Самый простой способ проверить, существует ли элемент, это просто вызвать find_element внутри try/catch.

B) Да, я всегда стараюсь идентифицировать элементы без использования их текста по двум причинам:

  1. текст с большей вероятностью изменится;
  2. если это важно для вас, вы не сможете запускать тесты для локализованных сборок.

решение либо:

  1. Вы можете использовать xpath, чтобы найти родительский элемент или элемент-предок, который имеет идентификатор или какой-либо другой уникальный идентификатор, а затем найти его дочерний / дочерний элемент, который соответствует или;
  2. youможет запросить идентификатор или имя или какой-либо другой уникальный идентификатор для самой ссылки.

Для последующих вопросов, используя try/catch, можно узнать, существует ли элемент или нет, и хорошие примерыожидания можно найти здесь: http://seleniumhq.org/docs/04_webdriver_advanced.html

42 голосов
/ 23 марта 2016

Ни одно из предложенных решений не показалось мне самым простым, поэтому я бы хотел добавить свой собственный способ.

По сути, вы получаете список элементов вместо просто элемента, а затем подсчитываетеРезультаты;если это ноль, то он не существует.Пример:

if driver.find_elements_by_css_selector('#element'):
    print "Element exists"

Обратите внимание на "s" в find_elements_by_css_selector, чтобы убедиться, что он может быть исчисляемым.

РЕДАКТИРОВАТЬ : я проверял len( изсписок, но я недавно узнал, что пустой список ложный, так что вам не нужно получать длину списка вообще, оставляя для еще более простой код.

Кроме того, в другом ответе говорится, что использование xpath более надежно, что просто неверно.См. В чем разница между css-selector и Xpath?что лучше (в зависимости от производительности и для кросс-браузерного тестирования)?

3 голосов
/ 16 ноября 2018

Решение без 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
2 голосов
/ 13 марта 2018

Так же, как Брайан, но добавьте к этому ответу от 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)
0 голосов
/ 31 октября 2018

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'

0 голосов
/ 10 сентября 2018

Вы также можете сделать это более кратко, используя

driver.find_element_by_id("some_id").size() != 0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...