Document ID: /fineweb-2-swissfilter-quality_10-filterrobots/filtered/03598.jsonl.gz/3186

Mit Selenium XPath Tabellen, Zellen und Inhalte lokalisieren
Wie bereits in den vorangegangenen Artikeln beschrieben, lassen sich Inhalte generell über die By.Id(), By.name() oder By.cssSelector() Methoden ansprechen. Bei Tabellen und insbesondere bei Zellen ist es aber so, dass man diese eher selten (bis gar nicht) mit Ids, Namen oder Ähnlichem versieht.
Mit der
By.xpath() Methode können wir jedes Element direkt und zweifelsfrei ansprechen. Sogar verschachtelte Tabellen (das sind z.B Tabellen in Tabellen) lassen sich hiermit abdecken.
Für die Praxisanwendung ist allerdings die Erstellung korrekter XPaths entscheidend. Hierfür ist das Wissen der DOM Struktur sowie Eltern- und Kindelementen Voraussetzung. Wir veranschaulichen dies an mehreren Beispielen, so dass die Methodik klar und verständlich ist und Sie am Ende gar der Auffassung sein könnten, dass XPath Strukturen gar nicht so schwer sind. Sie sind es nämlich überhaupt nicht.
Einfache Tabellen
Nehmen wir an wir haben eine einfache Tabelle mit mehreren Spalten sowie Zeilen. Im Sourcecode sieht dies in etwas so aus
<html>
<head>
<title>Einfache Tabelle</title>
</head>
<body>
<table name="tabone" id="tabone" width="100%">
<tbody>
<tr>
<td>erste zeile & erste spalte</td>
<td>erste zeile & zweite spalte</td>
</tr>
<tr>
<td>zweite zeile & erste spalte</td>
<td>zweite zeile & zweite spalte</td>
</tr>
</tbody>
</table>
</body>
Ergibt folgende Tabelle
Sie möchten nun die Zelle in der zweiten Spalte und der zweiten Zeile (oben fett markiert) erreichen. Wir lösen dies ganz einfach mit XPath. Die Struktur wird folgendermassen aufgebaut:
//table/tbody/tr[2]/td[2]
// so fängt jede XPath Struktur an
table : Dies ist das erste Elternelement vom Typ „table“ auf der HTML Site, usw.
Weshalb steht nun eine «2» als Index hinter TR und TD? Die Erklärung hierfür ist ganz einfach. Wir sprechen hier auch von Kindelementen. Sowohl TR als auch TD kam bereits mehrfach auf der Site vor. Innerhalb der Strukur (der Tabelle) ist das TR Tag in der zweiten Zeile das zweite (das erste kommt bereits ins Zeile 1 vor), innerhalb des TR Tags kommt das von uns gewollte TD auch als zweites vor (TD Tag davor markiert die erste Spalte). Somit zählt man ausgehend vom vorhergehenden Knoten (Node), hier TR, den Index, hier eben «2».
Das ist eigentlich schon alles. Mehr gibt es nicht wissen. In der Praxis ist es aber so, dass sehr komplexe Konstruktionen leicht Verwirrung hervorrufen. Es ist nicht immer so leicht, XPaths auf Anhieb fehlerfrei zu erstellen.
Verschachtelte Tabellen
Etwas schwieriger wird es, wenn Tabellen innerhalb von Tabellen vorkommen. Man spricht hier auch von verschachtelten Tabellen (nested tables). Mit oben erwähnter Vorgehensweise ist es aber trotzdem leicht zu bewältigen.
Die Tabelle sieht so aus
Der entsprechende XPath wird so aufgebaut, dass er im zweiten
table Elternteil beginnt (= Index «2»).
Somit erhalten wir folgende XPath Struktur: //table/tbody/tr[2]/td[2]/table/tbody/tr[2]/td[2]
Es wird somit nur der fett gedruckte Teil (innere Tabelle) an die äussere Tabelle angehängt. In Ihrem Selenium Code sieht das Ganze dann in etwa so aus
String zelleninhalt = driver.findElement(By.xpath("//table/tbody/tr[2]/td[2]/table/tbody/tr[2]/td[2]").getText();
Sie werden sich vielleicht fragen, weshalb wir nicht gleich die zweite Tabelle als Basis nehmen und XPath so erstellen //table[2]/tbody/tr[2]/td[2]
Da wir verschachtelt arbeiten, würde die nächste Tabelle ausserhalb angesprochen werden, aber eben nicht die innere. Deshalb muss auch die äussere Tabelle mit dabei stehen.
Hinweis: die Webtools von Mozilla Firefox erstellen XPath Strukturen mit Namespaces (meist «x»). Selenium kann diese nicht verarbeiten.
XPath mit Attributen deklarieren
Jetzt wird es kompliziert – aber nicht wirklich. Stellen Sie sich vor, im Sourcecode gibt es mehrere Verschachtelungen, zum Beispiel 5 Tabellen in einander. Sie möchten jetzt auf eine Zelle in der 4 Tabelle zugreifen. Neben wir an, Sie haben alle Tabellen korrekt mit IDs versehen (in der Praxis leider eher nicht der Fall). Dann können Sie die entsprechende Tabelle, in der sich die Zelle befindet, die Sie ansprechen möchten, direkt adressieren, nämlich anhand ihrer ID:
//table[@id="tabfour"]/tbody/tr[3]/td[7]
Mit ihrem gewonnen Wissen des vorangegangenen Texts wissen Sie, dass sich die Zelle in der dritten Zeile und der siebten Spalte befindet. Das ganze ist in der Tabelle mit der
id="tabfour" zu finden.
Im Selenium Code schreiben Sie dies in etwa so
String zelleninhalt = driver.findElement(By.xpath("//table[@id=\"tabfour\"]/tbody/tr[3]/td[7]").getText();
Bitte beachten Sie beiden Backspaces «\» vor den Anführungszeichen. Dies ist nötig, damit der JavaCompiler keinen Fehler wirft.
Spielen Sie ein bisschen selbst herum und gewöhnen Sie sich an XPath. Sie werden sehen, es ist halb so wild.
Am Ende sei noch ein Tipp oder Vielmehr ein Helferlein verraten: Sowohl für Mozilla Firefox als auch den Chrome Browser stehen diverse XPath Addons zur Verfügung. Diese erleichtern Ihre Arbeit enorm. Hierbei möchten besonders die Erweiterung für Firebug mit dem Namen Firepath empfehlen.