2012-05-30 20 views
6

Ich verwende Selen, um Text mit xpath auf meiner Webseite zu erhalten.Lesen von Text mit Selen-Webdriver (xpath)

Die Seite Tag-Struktur ist wie folgt -

<span id="data" class="firefinder-match"> 
    Seat Height, Laden 
    <sup> 
    <a class="speckeyfootnote" rel="p7" href="#">7</a> 
    </sup> 
</span> 

Wenn ich den folgenden Code verwenden -

driver.findElement(By.xpath("//span[@id='data']")).getText(); 

ich das Ergebnis zu erhalten = Seat Height, Laden 7

Aber ich das vermeiden wollen, lesen Text innerhalb der <sup> Tags und erhalten Sie die Ergebnis Seat Height, Laden

Bitte lassen Sie mich wissen, welchen xpath-Ausdruck ich verwenden kann, um mein gewünschtes Ergebnis zu erhalten.

+3

Um. Im einfachen XPath (das Strings und nicht nur WebElements zurückgeben könnte), könnten Sie '// span [@ id = 'data']/text() [1]' verwenden. Eine mögliche Lösung, die ich mir vorstellen kann, verwendet JS, die zweite erhält den ganzen Text und löscht dann alles aus den untergeordneten Elementen. Beide Lösungen sind eher hässlich und ich würde gerne eine schönere sehen. Wie auch immer, wenn es in vernünftiger Zeit keine Antwort gibt, werde ich es posten. –

+1

Warum Xpath ist Ihre einzige Option? Webdriver braucht am längsten, um ein Element nach dem xpath – Amey

+0

zu finden. Ich benutze xpath nur, weil ich damit vertraut bin. Wenn es einen anderen Weg gibt, mein Problem zu lösen, werde ich dankbar sein. –

Antwort

7

Ich kenne keine Möglichkeit, dies in Selen zu tun, also gibt es meine JS-Lösung. Die Idee ist, alle untergeordneten Elemente des Elements (einschließlich der Textknoten) zu erhalten und dann nur die Textknoten auszuwählen. Möglicherweise müssen Sie einige .trim() (oder JS äquivalente) Aufrufe hinzufügen, um nicht benötigte Leerzeichen zu entfernen.

Der gesamte Code:

WebElement elem = driver.findElement(By.id("data")); 
String text; 
if (driver instanceof JavascriptExecutor) { 
    text = ((JavascriptExecutor)driver).executeScript(
      "var nodes = arguments[0].childNodes;" + 
      "var text = '';" + 
      "for (var i = 0; i < nodes.length; i++) {" + 
      " if (nodes[i].nodeType == Node.TEXT_NODE) {" + 
      "  text += nodes[i].textContent;" + 
      " }" + 
      "}" + 
      "return text;" 
      , elem); 
} 

Und nur die JS für bessere Lesbarkeit.

var nodes = arguments[0].childNodes; 
var text = ''; 
for (var i = 0; i < nodes.length; i++) { 
    if (nodes[i].nodeType == Node.TEXT_NODE) { 
     text += nodes[i].textContent; 
    } 
} 
return text; 
+0

Hey nette Lösung, um das Ergebnis durch die JS zu bekommen. Aber ich möchte fragen, ob es etwas wie ein! Operator in xpath, mit dem wir bestimmte Tags vernachlässigen können. –

+1

Ja, da ist. Es wird jedoch in diesem speziellen Fall nicht funktionieren, da Sie immer noch das äußere Element auswählen und alle untergeordneten Elemente standardmäßig enthält. Der Textknoten ist auch ein Kindelement davon und ein gewöhnlicher Parser könnte es bekommen. WebDriver ist kein gewöhnlicher Parser und hat diese Funktionalität nicht. Noch. Wenn Sie einen bestimmten XPath kennen möchten, fragen Sie ihn. –