web-dev-qa-db-fra.com

Comment obtenir le texte d'un élément dans Selenium WebDriver, sans inclure le texte de l'élément enfant?

<div id="a">This is some
   <div id="b">text</div>
</div>

Obtenir "This is some" n'est pas anodin. Par exemple, cela renvoie "Ceci est du texte":

driver.find_element_by_id('a').text

Comment obtenir de manière générale le texte d'un élément spécifique sans inclure le texte de ses enfants?

(Je fournis une réponse ci-dessous mais laissera la question ouverte au cas où quelqu'un pourrait trouver une solution moins hideuse).

32
josh

Voici une solution générale:

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)

L'élément passé à la fonction peut être quelque chose obtenu à partir des méthodes find_element...() (c'est-à-dire qu'il peut être un objet WebElement).

Ou si vous n'avez pas jQuery ou ne voulez pas l'utiliser, vous pouvez remplacer le corps de la fonction ci-dessus par ceci:

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) 

J'utilise en fait ce code dans une suite de tests.

24
Louis

Vous n'avez pas à effectuer de remplacement, vous pouvez obtenir la longueur du texte des enfants et la soustraire de la longueur totale, puis la découper dans le texte d'origine. Cela devrait être sensiblement plus rapide.

4
kreativitea
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
3
josh