Поиск элементов веб-страницы при помощи CSS-селекторов предпочтительнее использования XPath, так как CSS удобнее для визуального восприятия, кроме того, есть мнение, что выполняться программа будет быстрее.
Эта статья - своеобразная памятка пользователю Selenium WebDriver о том, как использовать CSS-селекторы для поиска элементов веб-страницы.
Ищем веб-элемент ПО АТРИБУТУ.
Основная формула для поиска элемента по атрибуту с помощью CSS-селектора такова:
css = тэг_элемента[<название_атрибута>='<значение>']
Итак, допустим, у нас есть следующая строка для поиска:
<input type="text" id="someId" name="someName" class="someForm">
Найдём её:
WebElement someName = driver.findElement(By.cssSelector("input[name='someName']"));
Сокращенная форма поиска по атрибуту.
Для атрибутов ID и CLASS существует сокращенная форма "поиска по атрибуту"
для ID:
driver.findElement(By.cssSelector("input#someId")) ; // или, даже, так driver.findElement(By.cssSelector("#someId"));
для CLASS:
driver.findElement(By.cssSelector("input.someForm"));
// или же просто
driver.findElement(By.cssSelector(".someForm"));
Само собой, нужно иметь в виду, что при поиске элемента по атрибуту CLASS может обнаружится несколько веб-элементов с одинаковым значением атрибута. Если вы захотите использовать все - замените метод findElement на findElements, иначе придется довольствоваться первым найденным элементом.
Ищем веб-элемент ПО НЕСКОЛЬКИМ АТРИБУТАМ.
Иногда, для корректного выбора веб-элемента, необходимо указать несколько атрибутов в css-селекторе:
<div class="someClass" style="display:none">
в этом примере значение display может быть либо none, либо block. Как же выбрать только видимые элементы ? Вот так:
driver.findElement(By.cssSelector("div[class='someClass'] [style='display:block']"));
Ищем веб-элемент - ПОТОМОК
Вот у нас есть HTML код:
<div id="logotype">
<img src="./logotype.png" />
</div>
Как получить доступ к IMG при помощи cssSelector ? При помощи вот такой нехитрой конструкции:
driver.findElement(By.cssSelector("div#logo img"));
А если ПОТОМКОВ НЕСКОЛЬКО ?
Как получить доступ к конкретному фрукту из меню ?
<ul id="fruit">
<li>Apple</li>
<li>Orange</li>
<li>Banana</li>
</ul>
Используем псевдокласс :nth-of-type
driver.findElement(By.cssSelector("ul#fruit li:nth-of-type(2)"));
Найдет для нас элемент под номером 2, то есть Апельсин(Orange). Надо отметить, что нумерация потомков начинается с 1, а не с 0.
Если получить последнего потомка для элемента, можно использовать псевдокласс :last-child
driver.findElement(By.cssSelector("ul#fruit li:last-child"));
Атрибуты, генерируемые "на лету"
Очень часто элементы веб-страницы содержат атрибуты, генерируемые, так сказать, "на лету", то есть значение атрибута веб-элемента зависит от действий пользователя на странице. Вот, например:
<div id="123_randomId">
<div id="randomId_456">
<div id="789_pattern_randomId">
как же осуществить поиск нужного элемента, скажем, содержащего слово randomId в атрибуте id. Давайте разбираться..
Значение атрибута НАЧИНАЕТСЯ С
Что бы найти веб-элемент, значение определенного атрибута которого начинается с определенных символов, используется конструкция ^=
driver.findElement(By.cssSelector("div[id^='123']"));
относительно примера, приведенного выше, мы получим самый первый DIV c ID = "123_randomId"
Значение атрибута ЗАКАНЧИВАЕТСЯ НА
Что бы найти веб-элемент, значение определенного атрибута которого заканчивается определенным набором символов, используется конструкция $=
driver.findElement(By.cssSelector("div[id$='456']"));
относительно примера, приведенного выше, мы получим второй DIV c ID = "randomId_456"
Значение атрибута СОДЕРЖИТ
Что бы найти веб-элемент, значение определенного атрибута которого содержит в себе определенный набор символов, используется конструкция *=
driver.findElement(By.cssSelector("div[id*='_pattern_']"));
// кроме того, мы можем использовать метод 'contains()'
driver.findElement(By.cssSelector("div:contains('_pattern_')"));
относительно примера, приведенного выше, мы получим третий, последний, DIV c ID = "789_pattern_randomId"
Поиск по принципу "ВСЕ, КРОМЕ".
Бывают случаи, когда среди множества похожих веб-элементов нужно отобрать те, которые имеют какое-то отличие.
Взгляните на следующий пример:
<div class="day past calendar-2017-02-13 calendar-dow-1 unavailable">
<div class="day today calendar-2017-02-14 calendar-dow-2 unavailable">
<div class="day calendar-2017-02-15 calendar-dow-3">
<div class="day calendar-2017-02-16 calendar-dow-4">
Представьте, что нам нужно выбрать только те DIV, которые, в атрибуте class не содержат слова unavailable.
Для этой цели используется CSS-селектор NOT, вот так:
driver.findElements(By.cssSelector("div[class*=calendar-day-]:not([class*='unavailable'])"));"