Как получить текст элемента в Selenium WebDriver (через Python api) без включения текста дочернего элемента?
<div id="a">This is some
<div id="b">text</div>
</div>
Получение "Это некоторые" является нетривиальным. Например, это возвращает "Это какой-то текст":
driver.find_element_by_id('a').text
Как один, в общем, получить текст конкретного элемента без включения его содержимого?
(Я предоставляю ответ ниже, но оставит вопрос открытым, если кто-то может придумать менее отвратительное решение).
Ответы
Ответ 1
Здесь общее решение:
def get_text_excluding_children(driver, element):
return driver.execute_script("""
return jQuery(arguments[0]).contents().filter(function() {
return this.nodeType == Node.TEXT_NODE;
}).text();
""", element)
Элемент, переданный функции, может быть чем-то полученным из методов find_element...()
(т.е. может быть объектом WebElement
).
Или, если у вас нет jQuery или вы не хотите его использовать, вы можете заменить тело функции выше:
return self.driver.execute_script("""
var parent = arguments[0];
var child = parent.firstChild;
var ret = "";
while(child) {
if (child.nodeType === Node.TEXT_NODE)
ret += child.textContent;
child = child.nextSibling;
}
return ret;
""", element)
Я действительно использую этот код в тестовом наборе.
Ответ 2
Вам не нужно выполнять замену, вы можете получить длину текста для детей и вычесть из общей длины и отрезать в исходный текст. Это должно быть значительно быстрее.
Ответ 3
def get_true_text(tag):
children = tag.find_elements_by_xpath('*')
original_text = tag.text
for child in children:
original_text = original_text.replace(child.text, '', 1)
return original_text