это упрощенная структура HTML, которую я просматриваю:
<div class="main">
...other stuff...
<td class="child">44</td>
<td class="child">59</td>
<td class="child">11</td>
</div>
<div class="main">
...other stuff...
<td class="child">5</td>
<td class="child">14</td>
<td class="child">98</td>
</div>
...this kind of structure repeats with similar numbers a few more times but with identical class names
Мне нужно извлечь все числа под первым найденным основным классом, поэтому я сделал запрос для поиска первого основного и всего td с определенным классом под ним. Может кто-нибудь дать мне подсказку, что я делаю неправильно, так как этот запрос дает мне все числа из всех td с классом "child" во всех "главных" div's:
List<WebElement> koefi = driver.findElements(By.xpath("//div[@class='main'][1]//td[@class='child']"));
Что я делаю неправильно или моя логика правильная, но я пропускаю некоторые другие части html, которые я не вставлял здесь, так как структура слишком громоздка..?
Спасибо!!
ps: Я тоже это пробовал, но опять же, я получаю содержимое всех td с "дочерним" классом, а не только с первого "основного".
List<WebElement> koefi = driver.findElements(By.xpath("//*[1][@class='main']//td[@class='child']"));
UPDATE: мне удалось решить мою проблему, сначала получив первое появление "основного" div, которое по умолчанию найдено функцией.findElement:
WebElement element = driver.findElement(By.xpath("//*[1][@id='main']"));
И затем извлечение с помощью.findElements функции "дочерних" классов:
List<WebElement> kk = element.findElements(By.className("child"));
Я все еще не могу понять, почему не работает.findElements с моим xpath или работает слишком хорошо, он извлекает каждый "основной" класс, а не только первый. И оригинальный HTML слишком большой, чтобы вставить сюда, поэтому я не хочу беспокоить вас, ребята!
Более чистое решение состояло бы в том, чтобы сначала захватить все div
с main
div
, например:
List<WebElement> allDivs = driver.findElements(By.className("main"));
Затем, как вы указали, найдите все td
с child
td
класса, например:
List<WebElement> tds = allDivs[0].findElements(By.className("child"));
После этого это всего лишь вопрос повторения всех "tds" и чтения ваших ценностей.
Вы скажете в комментарии, что
"главные" не являются прямыми братьями и сестрами
поэтому я подозреваю, что вы ошибаетесь в общей ошибке, связанной с определением //
в XPath. Путь
//div[@class='main'][1]
не выбирает первый "основной" div в документе. Причиной этого является то, что //
является сокращением для /descendant-or-self::node()/
(включая начальную и конечную косые черты), поэтому этот путь на самом деле означает
/descendant-or-self::node()/child::div[@class='main'][1]
Когда вы видите его полностью расширенным, вы понимаете, что [1]
относится к child::
step, а не к поиску потомков, то есть вы получите все элементы div
в документе, которые имеют класс "main", и являются первыми div-with-class-main под соответствующими родительскими элементами. Если ваш фактический HTML
<div>
<div class="main">...</div>
</div>
<div>
<div class="main">...</div>
</div>
то XPath выберет оба из них (они оба являются первыми под родителями). Если вы просто хотите получить первую в документе, тогда вы должны использовать ось descendant::
/descendant::div[@class='main'][1]
который даст вам только первый совпадающий потомок.
//*[1][@class='main']
означает каждый элемент в документе, который является первым дочерним элементом его родителя и имеет класс main, в отличие от //*[@class='main'][1]
который будет каждым элементом, который является первым элементом-с-class-main в его родителе.
<div class="main">
являются братьями и сестрами?