Solución:
Puede eliminar el texto del nodo secundario de todo el texto
all_text = driver.find_element_by_xpath("//whatever").text
child_text = driver.find_element_by_xpath("//subchild").text
parent_text = all_text.replace(child_text, '')
Tenga en cuenta que el enfoque de reemplazo mencionado por @Guy no funciona para muchas estructuras.
Por ejemplo, tener esta estructura:
<div>
Hello World
<b>e</b>
</div>
El texto principal sería Hello World e
, el texto secundario sería e
, y el reemplazo resultaría en Hllo World
en lugar de Hello World
.
Una solucion segura
Para obtener el propio texto de un elemento de manera segura, debe iterar sobre los elementos secundarios del nodo y concanear los nodos de texto. Como no puede hacer eso en Selenium puro, debe ejecutar código JS.
OWN_TEXT_SCRIPT = "if(arguments[0].hasChildNodes()){var r="";var C=arguments[0].childNodes;for(var n=0;n<C.length;n++){if(C[n].nodeType==Node.TEXT_NODE){r+=' '+C[n].nodeValue}}return r.trim()}else{return arguments[0].innerText}"
parent_text = driver.execute_script(OWN_TEXT_SCRIPT, elem)
El script es una versión reducida de esta sencilla función:
if (arguments[0].hasChildNodes()) {
var res="";
var children = arguments[0].childNodes;
for (var n = 0; n < children.length; n++) {
if (children[n].nodeType == Node.TEXT_NODE) {
res += ' ' + children[n].nodeValue;
}
}
return res.trim()
}
else {
return arguments[0].innerText
}
Recientemente tuve un problema similar, donde el selenio siempre me dio todo el texto dentro del elemento, incluidos los intervalos. Terminé dividiendo la cadena con una nueva línea ” n”. por ejemplo
all_text = driver.find_element_by_xpath(xpath).text
req_text = str.split(str(all_text ), "n")[0]