Пользователь
0,0
рейтинг
18 февраля 2015 в 16:55

Разработка → Selenium для Python. Глава 4. Поиск элементов tutorial

Продолжение перевода неофициальной документации Selenium для Python.
Перевод сделан с разрешения автора Baiju Muthukadan.
Оригинал можно найти здесь.

Содержание:


1. Установка
2. Первые Шаги
3. Навигация
4. Поиск Элементов
5. Ожидания
6. Объекты Страницы
7. WebDriver API
8. Приложение: Часто Задаваемые Вопросы

4. Поиск элементов


Существует ряд способов поиска элементов на странице. Вы вправе использовать наиболее уместные для конкретных задач. Selenium предоставляет следующие методы поиска элементов на странице:

  • find_element_by_id
  • find_element_by_name
  • find_element_by_xpath
  • find_element_by_link_text
  • find_element_by_partial_link_text
  • find_element_by_tag_name
  • find_element_by_class_name
  • find_element_by_css_selector

Чтобы найти все элементы, удовлетворяющие условию поиска, используйте следующие методы (возвращается список):

  • find_elements_by_name
  • find_elements_by_xpath
  • find_elements_by_link_text
  • find_elements_by_partial_link_text
  • find_elements_by_tag_name
  • find_elements_by_class_name
  • find_elements_by_css_selector

[Как вы могли заметить, во втором списке отсутствует поиск по id. Это обуславливается особенностью свойства id для элементов HTML: идентификаторы элементов страницы всегда уникальны. — Прим. пер.]

Помимо общедоступных (public) методов, перечисленных выше, существует два приватных (private) метода, которые при знании указателей объектов страницы могут быть очень полезны: find_element and find_elements.

Пример использования:

from selenium.webdriver.common.by import By

driver.find_element(By.XPATH, '//button[text()="Some text"]')
driver.find_elements(By.XPATH, '//button')

Для класса By доступны следующие атрибуты:

ID = "id"
XPATH = "xpath"
LINK_TEXT = "link text"
PARTIAL_LINK_TEXT = "partial link text"
NAME = "name"
TAG_NAME = "tag name"
CLASS_NAME = "class name"
CSS_SELECTOR = "css selector"

4.1. Поиск по Id


Используйте этот способ, когда известен id элемента. Если ни один элемент не удовлетворяет заданному значению id, будет вызвано исключение NoSuchElementException.

Для примера, рассмотрим следующий исходный код страницы:

<html>
 <body>
  <form id="loginForm">
   <input name="username" type="text" />
   <input name="password" type="password" />
   <input name="continue" type="submit" value="Login" />
  </form>
 </body>
<html>

Элемент form может быть определен следующим образом:

login_form = driver.find_element_by_id('loginForm')

4.2. Поиск по Name


Используйте этот способ, когда известен атрибут name элемента. Результатом будет первый элемент с искомым значением атрибута name. Если ни один элемент не удовлетворяет заданному значению name, будет вызвано исключение NoSuchElementException.

Для примера, рассмотрим следующий исходный код страницы:

<html>
 <body>
  <form id="loginForm">
   <input name="username" type="text" />
   <input name="password" type="password" />
   <input name="continue" type="submit" value="Login" />
   <input name="continue" type="button" value="Clear" />
  </form>
</body>
<html>

Элементы с именами username и password могут быть определены следующим образом:

username = driver.find_element_by_name('username')
password = driver.find_element_by_name('password')

Следующий код получит кнопку “Login”, находящуюся перед кнопкой “Clear”:

continue = driver.find_element_by_name('continue')

4.3. Поиск по XPath


XPath – это язык, использующийся для поиска узлов дерева XML-документа. Поскольку в основе HTML может лежать структура XML (XHTML), пользователям Selenium предоставляется возможность посредоством этого мощного языка отыскивать элементы в их веб-приложениях. XPath выходит за рамки простых методов поиска по атрибутам id или name (и в то же время поддерживает их), и открывает спектр новых возможностей, таких как поиск третьего чекбокса (checkbox) на странице, к примеру.

Одно из веских оснований использовать XPath заключено в наличии ситуаций, когда вы не можете похвастать пригодными в качестве указателей атрибутами, такими как id или name, для элемента, который вы хотите получить. Вы можете использовать XPath для поиска элемента как по абсолютному пути (не рекомендуется), так и по относительному (для элементов с заданными id или name). XPath указатели в том числе могут быть использованы для определения элементов с помощью атрибутов отличных от id и name.

Абсолютный путь XPath содержит в себе все узлы дерева от корня (html) до необходимого элемента, и, как следствие, подвержен ошибкам в результате малейших корректировок исходного кода страницы. Если найти ближайщий элемент с атрибутами id или name (в идеале один из элементов-родителей), можно определить искомый элемент, используя связь «родитель-подчиненный». Эти связи будут куда стабильнее и сделают ваши тесты устойчивыми к изменениям в исходном коде страницы.

Для примера, рассмотрим следующий исходный код страницы:

<html>
 <body>
  <form id="loginForm">
   <input name="username" type="text" />
   <input name="password" type="password" />
   <input name="continue" type="submit" value="Login" />
   <input name="continue" type="button" value="Clear" />
  </form>
</body>
<html>

Элемент form может быть определен следующими способами:

login_form = driver.find_element_by_xpath("/html/body/form[1]")
login_form = driver.find_element_by_xpath("//form[1]")
login_form = driver.find_element_by_xpath("//form[@id='loginForm']")

  1. Абсолютный путь (поломается при малейшем изменении структуры HTML страницы)
  2. Первый элемент form в странице HTML
  3. Элемент form, для которого определен атрибут с именем id и значением loginForm

Элемент username может быть найден так:

username = driver.find_element_by_xpath("//form[input/@name='username']")
username = driver.find_element_by_xpath("//form[@id='loginForm']/input[1]")
username = driver.find_element_by_xpath("//input[@name='username']")

  1. Первый элемент form с дочерним элементом input, для которого определен атрибут с именем name и значением username
  2. Первый дочерний элемент input элемента form, для которого определен атрибут с именем id и значением loginForm
  3. Первый элемент input, для которого определен атрибут с именем name и значением username

Кнопка “Clear” может быть найдена следующими способами:

clear_button = driver.find_element_by_xpath("//input[@name='continue'][@type='button']")
clear_button = driver.find_element_by_xpath("//form[@id='loginForm']/input[4]")

  1. Элемент input, для которого заданы атрибут с именем name и значением continue и атрибут с именем type и значением button
  2. Четвертый дочерний элемент input элемента form, для которого задан атрибут с именем id и значением loginForm

Представленные примеры покрывают некоторые основы использования XPath, для более углубленного изучения рекомендую следующие материалы:


Существует также пара очень полезных дополнений (add-on), которые могут помочь в выяснении XPath элемента:

  • XPath Checker — получает пути XPath и может использоваться для проверки результатов пути XPath
  • Firebug — получение пути XPath — лишь одно из многих мощных средств, поддерживаемых этим очень полезным плагином
  • XPath Helper — для Google Chrome

4.4. Поиск гиперссылок по тексту гиперссылки


Используйте этот способ, когда известен текст внутри анкер-тэга [anchor tag, анкер-тэг, тег «якорь» — тэг — Прим. пер.]. С помощью такого способа вы получите первый элемент с искомым значением текста тэга. Если никакой элемент не удовлетворяет искомому значению, будет вызвано исключение NoSuchElementException.

Для примера, рассмотрим следующий исходный код страницы:

<html>
 <body>
  <p>Are you sure you want to do this?</p>
  <a href="continue.html">Continue</a>
  <a href="cancel.html">Cancel</a>
</body>
<html>

Элемент-гиперссылка с адресом «continue.html» может быть получен следующим образом:

continue_link = driver.find_element_by_link_text('Continue')
continue_link = driver.find_element_by_partial_link_text('Conti')

4.5. Поиск элементов по тэгу


Используйте этот способ, когда вы хотите найти элемент по его тэгу. Таким способом вы получите первый элемент с указанным именем тега. Если поиск не даст результатов, будет возбуждено исключение NoSuchElementException.

Для примера, рассмотрим следующий исходный код страницы:

<html>
 <body>
  <h1>Welcome</h1>
  <p>Site content goes here.</p>
</body>
<html>

Элемент заголовка h1 может быть найден следующим образом:

heading1 = driver.find_element_by_tag_name('h1')

4.6. Поиск элементов по классу


Используйте этот способ в случаях, когда хотите найти элемент по значению атрибута class. Таким способом вы получите первый элемент с искомым именем класса. Если поиск не даст результата, будет возбуждено исключение NoSuchElementException.

Для примера, рассмотрим следующий исходный код страницы:

<html>
 <body>
  <p class="content">Site content goes here.</p>
</body>
<html>

Элемент “p” может быть найден следующим образом:

content = driver.find_element_by_class_name('content')

4.7. Поиск элементов по CSS-селектору


Используйте этот способ, когда хотите получить элемент с использованием синтаксиса CSS-селекторов [CSS-селектор — это формальное описание относительного пути до элемента/элементов HTML. Классически, селекторы используются для задания правил стиля. В случае с WebDriver, существование самих правил не обязательно, веб-драйвер использует синтаксис CSS только для поиска — Прим. пер.]. Этим способом вы получите первый элемент удовлетворяющий CSS-селектору. Если ни один элемент не удовлетворяют селектору CSS, будет возбуждено исключение NoSuchElementException.

Для примера, рассмотрим следующий исходный код страницы:

<html>
 <body>
  <p class="content">Site content goes here.</p>
</body>
<html>

Элемент “p” может быть определен следующим образом:

content = driver.find_element_by_css_selector('p.content')

На Sauce Labs есть хорошая документация по селекторам CSS.
От переводчика: советую также обратиться к следующим материалам:
Егор @penguino
карма
13,0
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Спецпроект

Самое читаемое Разработка

Комментарии (6)

  • 0
    А как вы в селениуме подписываетесь на евенты? Допустим, на сайте есть блок, который плавно двигается из точки А в точку Б и когда он в точке Б будет на месте — необходимо сделать проверку, но не раньше. Можно ли в Селениум бросить евент из JS?
    • +1
      Да, можно выполнить любой js в контексте страницы.
      • 0
        Это JS в контексте страницы, тут никаких проблем, а обратная связь. Что-то вроде:

        window.launchCoolAnimation({
          target: object,
          onComplete: function () {
            SELENIUM.on_complete();
          }
        })
        


        • 0
          В любом случае надо ждать какого-то условия, варианта два — ожидание селектора, либо ожидание изменение состояния какого-то обьекта в js. В данном случае, ждете в асинхронном вызове жс-а (JsonWireProtocol) пока ваша функция вернет какое-либо значение, которое означает что движение блока завершилось ( либо же ожидаете изменение в css/html), проверяя событие каждые N секунд, но не более N*M секунд. Если функция возвращает нужное значение — вызываете launchCoolAnimation. В зависимости от фреймворка (или биндингов) можно юзать и eventHandler's, например (browserevent), хотя это можно и самому реализовать достаочно легко.
          • 0
            Дякую.
  • +1
    Вообще если честно этим я и не люблю кучи методов by class, by id и тд, в то время как уже давно есть более быстрые и более удобные css selectors. Единственный минус — это отсутствие поиска по тексту, т.к. его депрекейтнули, но и искать по тексту тоже не лучший вариант :)

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.