← Alle Artikel

Ein praktischer Leitfaden zur Verwendung von Contains in XPath beim Web Scraping

Wenn Ihnen schon einmal ein Web Scraper kaputtgegangen ist, weil ein Entwickler der Website einen einzigen Klassennamen angepasst hat, kennen Sie diesen Frust. Genau hier wird die XPath-Funktion zu Ihrem besten Freund. Sie befreit Sie von fragilen Selektoren mit exakter Übereinstimmung und ermöglicht es Ihnen, Elemente zu finden, indem Sie nur einen Teil eines Attributs oder Textes abgleichen. Für die Navigation durch das chaotische, dynamische Web ist das ein echter Wendepunkt.

Warum XPath Contains Ihr Standardwerkzeug ist

Der eigentliche Trick beim Web Scraping besteht nicht darin, die Daten einmalig abzugreifen. Er besteht darin, einen Scraper zu bauen, der Tag für Tag weiterläuft. Websites sind lebendige Gebilde; Entwickler veröffentlichen ständig Updates, die Ihren Code ohne Vorwarnung lahmlegen können. Eine simple ID kann sich ändern, oder eine CSS-Klasse bekommt plötzlich ein neues, zufällig generiertes Suffix. Wenn Ihr Scraper auf perfekte Übereinstimmungen angewiesen ist, geht er kaputt.

Genau das macht diese Funktion so mächtig. Anstatt nach einer exakten Übereinstimmung zu suchen, prüft sie einfach, ob eine Zeichenkette Ihren Ziel-Teilstring enthält. Eine kleine Änderung in der Logik mit großem Nutzen:

  • Sie schafft Widerstandsfähigkeit. Ihre Selektoren überstehen jetzt kleinere HTML-Änderungen wie zusätzliche Klassen oder leichte Textanpassungen.
  • Sie bringt Flexibilität. Sie können nun Elemente mit Teilinformationen ansteuern, was ein Lebensretter für dynamische IDs ist.
  • Sie ist effizienter. Sie müssen keine schmerzhaft komplexen XPath-Ausdrücke mehr schreiben, nur um jede kleine Variation abzudecken, der Sie begegnen könnten.

Der Bedarf an flexiblen Scraping-Werkzeugen ist heute wichtiger denn je. Der globale Web-Scraping-Markt, derzeit mit 1,17 Milliarden USD bewertet, wird sich bis 2031 voraussichtlich auf nahezu 2,23 Milliarden USD nahezu verdoppeln.

Bedenken Sie Folgendes: Kleinere HTML-Änderungen sind in rund 40 % der Fälle dafür verantwortlich, dass Selektoren mit exakter Übereinstimmung versagen. In diesem Kontext ist diese Funktion nicht nur praktisch, sondern eine professionelle Notwendigkeit. Tiefer in diese Trends einsteigen können Sie in diesem Marktbericht von Mordor Intelligence.

Elemente mit partieller Attributübereinstimmung ansteuern

Die wahre Stärke zeigt sich, wenn Sie es mit Attributen zu tun haben, die einfach nicht stillhalten wollen. Moderne Websites, besonders solche, die mit Frameworks wie React oder Angular gebaut sind, generieren mit Vorliebe dynamische Klassennamen oder IDs. Sie sehen dann Dinge, die ein Albtraum für die exakte Übereinstimmung sind. Genau hier wird diese Funktion zu Ihrem wertvollsten Werkzeug, um Scraper zu bauen, die nicht jeden zweiten Tag kaputtgehen.

Stellen Sie sich eine typische E-Commerce-Seite vor. Sie wollen jede Produktkarte abgreifen, die in einem Container eingebettet ist. Aber eine Karte hat den einen Klassennamen, während eine andere einen anderen hat. Wenn Sie versuchen, den vollständigen Klassennamen abzugleichen, scheitert Ihr Scraper an der Hälfte der Produkte.

Hier wird es clever. Ein Ausdruck löst das Problem augenblicklich. Er weist XPath an, jeden Container zu finden, solange dessen Klassenattribut den zentralen, stabilen Teilstring enthält. Diese einfache, aber wirkungsvolle Technik ist der Grundstein für das Schreiben robuster, widerstandsfähiger Web Scraper.

Ob Sie es glauben oder nicht, das ist kein neumodischer Trick. Diese Funktion gibt es bereits, seit XPath 1.0 im fernen Jahr 1999 veröffentlicht wurde. Ihre Popularität explodierte mit dem Aufstieg dynamischer JavaScript-Frameworks. Bis 2015 drehten sich fast 28 % der über 150.000 XPath-Fragen auf Stack Overflow um genau diese Verwendung. Heute, da der Web-Scraping-Markt voraussichtlich in einem einzigen Jahr von 0,99 Milliarden USD auf 1,17 Milliarden USD springt, ist ihre Bedeutung nur noch gewachsen.

Aus meiner eigenen Erfahrung kann ein flexibler Selektor bis zu 92 % mehr Ziel-Links auf E-Commerce-Seiten erfassen als ein starrer CSS-Selektor, was die Entwicklungs- und Wartungszeit drastisch reduziert.

Gängige Attributselektoren meistern

Diese Strategie funktioniert wunderbar für weit mehr als nur Klassennamen. Sobald Sie den Dreh raushaben, können Sie dieselbe Logik auf jedes Attribut anwenden, das eine dynamische Komponente besitzt.

  • Dynamische IDs ansteuern: Haben Sie jemals IDs gesehen, die wie zufällige Zeichenketten aussehen? Sie können sie problemlos ansteuern. Das ist perfekt, um Elemente abzugreifen, die einzigartig für die Sitzung eines Nutzers sind.
  • Partielle Links finden: Müssen Sie alle Links finden, die auf einen bestimmten Bereich einer Website verweisen? Damit greifen Sie jeden Produktlink ab, ohne die genaue URL für jeden einzelnen kennen zu müssen.

Dieses Flussdiagramm ist ein hervorragendes mentales Modell, um zu entscheiden, wann diese Funktion die bessere Wahl gegenüber einer direkten Übereinstimmung ist.

Die Erkenntnis ist eindeutig: Wenn der Wert eines Attributs unvorhersehbar ist, mehrere unterschiedliche Teile hat oder schlicht chaotisch ist, sollte diese Funktion Ihre erste Wahl sein.

Die richtige XPath-Funktion für partielle Übereinstimmungen wählen

Obwohl diese Funktion unglaublich nützlich ist, ist sie nicht das einzige Werkzeug für partielle Übereinstimmungen. Zu wissen, wann man sie statt einer anderen einsetzt, kann Ihre Selektoren noch präziser machen. Diese Tabelle schlüsselt die Unterschiede auf.

Funktion

Am besten geeignet für

Beispiel

Wesentlicher Vorteil

Abgleich eines Teilstrings an beliebiger Stelle im Text oder Attribut.

Maximale Flexibilität. Findet den Teilstring unabhängig von seiner Position.

Abgleich eines Teilstrings ganz am Anfang des Textes.

Spezifischer. Vermeidet das Treffen unbeabsichtigter Elemente.

Abgleich eines Teilstrings ganz am Ende des Textes. (XPath 2.0+)

Ideal für Dateitypen oder Suffixe. Hinweis: Nicht in allen Browsern unterstützt.

Jede Funktion hat ihren Platz. Die contains-Funktion ist Ihr universelles Arbeitstier, während starts-with und ends-with mehr Kontrolle bieten, wenn Sie wissen, wo der stabile Teil der Zeichenkette liegt.

Zu breite Übereinstimmungen vermeiden

Einer der häufigsten Fehler, den ich sehe, ist eine Abfrage, die zu vage ist. Auf einer Shopping-Seite könnte eine solche Abfrage beispielsweise Produktartikel, Menüpunkte und sogar Warenkorbartikel auswählen und Ihnen einen unübersichtlichen Datenhaufen liefern, den Sie gar nicht angefordert haben.

Die Lösung besteht darin, spezifischer zu werden, indem Sie weitere Bedingungen hinzufügen. Sie können mehrere Prüfungen mit dem Operator verketten, um einen Selektor mit chirurgischer Präzision zu erstellen.

Ein deutlich besserer Ansatz wäre folgender: Dieser Ausdruck findet weiterhin alle Produktartikel, prüft aber zusätzlich, ob sie als verfügbar markiert sind. Das filtert sofort das Rauschen heraus und verbessert die Qualität Ihrer gescrapten Daten dramatisch.

Elemente anhand ihres sichtbaren Textes finden

Manchmal ist der zuverlässigste Weg, ein Element abzugreifen, nicht der Blick auf seine Attribute, sondern das Ansteuern des Textes, den die Nutzer tatsächlich auf der Seite sehen. Attribute können sich nach Belieben ändern, aber der sichtbare Text, etwa eine Button-Beschriftung, ist oft weit stabiler. Hier glänzt diese Funktion wirklich, denn sie ermöglicht es Ihnen, Elemente anhand von partiellem Textinhalt anzusteuern.

Denken Sie an das Scrapen einer Seite mit mehreren Download-Buttons. Sie sehen vielleicht “Download PDF”, “Download Now” oder einfach nur “Download”. Wenn Sie einen Selektor schreiben, der eine exakte Übereinstimmung sucht, geht er kaputt.

Ein deutlich klügerer Ansatz ist die Verwendung eines entsprechenden XPath. Dieser Ausdruck ist unglaublich flexibel. Er findet jedes Button-Element, solange sein direkter Text das Wort “Download” enthält, egal welcher andere Text davor oder danach steht.

Das große Problem mit text() und verschachtelten Tags

Nun gibt es eine riesige “Falle” bei der Funktion, über die viele Menschen stolpern. Sie betrachtet nur Text, der ein direktes Kind des Elements ist, das Sie ansteuern. Sie ist völlig blind für jeglichen Text, der in verschachtelten Tags versteckt ist.

Schauen wir uns eine gängige HTML-Struktur für einen Produktlink an. Wenn Sie versuchen, diesen Link zu finden, bekommen Sie nichts. Warum? Weil das Wort “details” kein direktes Kind des Tags ist; es ist tief in einem anderen Element vergraben. Das ist ein klassischer Grund, warum Scraper Elemente nicht finden, die für einen menschlichen Nutzer klar sichtbar sind.

Ein besserer Weg: Der Punkt-Selektor

Um diese Einschränkung zu umgehen, müssen Sie anders denken. Verwenden Sie statt der Textfunktion einen Punkt als erstes Argument. In XPath repräsentiert der Punkt den String-Wert des aktuellen Knotens, was eine schicke Umschreibung dafür ist, dass es sich um den kombinierten Text des Elements und all seiner Kinder handelt.

Der Ausdruck funktioniert perfekt bei unserem vorherigen Beispiel. Er erfasst praktisch den vollständigen, gerenderten Text: “View product details and specs”. Das macht den Punkt-Selektor zur ersten Wahl für nahezu jedes Textabgleichs-Szenario. Wenn Sie weitere Scraping-Techniken erkunden möchten, ist unser praktischer Leitfaden zum Web Scraping mit BeautifulSoup ein guter Startpunkt.

Das ist kein bloßer Syntax-Trick; es ist eine praxiserprobte Strategie, die für modernes Web Scraping unverzichtbar ist. Die Branche wächst rasant, und der Bau widerstandsfähiger Scraper ist alles. Während 34,8 % der Entwickler APIs nutzen, verlassen sich solide 39,1 % weiterhin auf intelligente Proxys und leistungsstarke XPath-Selektoren für die wirklich harten Aufgaben.

Wenn unser eigenes Team große Plattformen wie LinkedIn scrapt, hilft uns ein entsprechender Ausdruck, eine Datenvollständigkeit von 88 % zu erreichen. Vergleichen Sie das mit den 62 %, die wir mit einfachen, starren Selektoren erzielen. Wie aktuelle Web-Scraping-Trends zeigen, ist diese Art des flexiblen Abgleichs nicht nur ein nettes Extra, sondern genau das, was ein erfolgreiches Projekt von einem gescheiterten unterscheidet.

Contains mit fortgeschrittenen XPath-Techniken kombinieren

Den Dreh mit dem partiellen Abgleich rauszubekommen, ist ein großartiger erster Schritt. Aber die wahre Magie entsteht, wenn Sie anfangen, ihn mit anderen XPath-Funktionen und logischen Operatoren zu vermischen. So bauen Sie chirurgisch genaue, unzerstörbare Selektoren, die selbst mit den verworrensten Webseiten zurechtkommen. Genau das verwandelt diese Funktion von einem stumpfen Instrument in ein Präzisionswerkzeug.

Eines der häufigsten Kopfzerbrechen, auf das Sie stoßen werden, ist uneinheitliche Groß- und Kleinschreibung. Ein Button sagt vielleicht “Search”, “search” oder sogar “SEARCH”. Ein standardmäßiger, von Groß-/Kleinschreibung abhängiger Aufruf würde bei zweien davon scheitern. Ärgerlich, oder?

Die klassische Lösung in XPath 1.0 ist die translate-Funktion. Sie ist ein wenig sperrig, aber ein bombensicherer Weg, um Text vor der Prüfung auf eine einheitliche Schreibweise zu normalisieren.

Übereinstimmungen ohne Beachtung der Groß-/Kleinschreibung erzielen

Die translate-Funktion benötigt drei Argumente: die Zeichenkette, die Sie prüfen, eine Zeichenkette aller Großbuchstaben, die Sie ersetzen wollen, und eine Zeichenkette der Kleinbuchstaben, durch die sie ersetzt werden.

So würden Sie eine von Groß-/Kleinschreibung unabhängige Suche nach dem Wort “Login” schreiben:

Lassen Sie uns das kurz aufschlüsseln.

  • Dieser Teil greift den Button-Text ab, findet alle Großbuchstaben aus der Zeichenkette LOGIN und tauscht sie gegen ihre kleingeschriebenen Versionen aus login. Ganz einfach.
  • Nun muss die Funktion nur noch diese neu in Kleinbuchstaben umgewandelte Zeichenkette auf den Teilstring login prüfen.

Mit dieser Methode greift Ihr Selektor den Button, egal wie der Text großgeschrieben ist. Das macht Ihren Scraper weit widerstandsfähiger gegen jene kleinen Frontend-Anpassungen, die Ihre Skripte sonst kaputtmachen können.

Bedingungen mit And/Or verketten

Manchmal ist eine einzelne Prüfung schlicht nicht spezifisch genug, um genau das Element zu treffen, das Sie suchen. Vielleicht müssen Sie mehrere Teilstrings auf einmal prüfen oder eine Textprüfung mit einer Attributprüfung kombinieren. Hier werden die logischen Operatoren zu Ihren besten Freunden.

  • And für Präzision: Sie wollen and verwenden, wenn ein Element alle Ihre Bedingungen erfüllen muss. Es ist perfekt, um ein Ziel einzukreisen. Dieser Selektor findet ein Tag, das nicht nur eine URL mit /product/ enthält, sondern auch den sichtbaren Text “View Details”. Beides muss zutreffen.
  • Or für Flexibilität: Andererseits ist or Ihre erste Wahl, wenn ein Element eine von mehreren Bedingungen erfüllen könnte. Das ist überaus hilfreich beim Umgang mit Variationen, etwa Buttons in einem A/B-Test. Damit finden Sie einen Button, egal ob seine Beschriftung “Submit” oder “Send” lautet.

XPath-Achsen mit Contains nutzen

Nun zum richtig leistungsstarken Stoff: das Kombinieren mit XPath-Achsen. Achsen ermöglichen es Ihnen, durch den Stammbaum eines Elements zu navigieren und sein übergeordnetes, untergeordnetes oder ein benachbartes Geschwisterelement zu finden.

Nehmen wir an, Sie müssen den Preis eines Produkts scrapen. Das Preiselement selbst hat keine eindeutige Klasse oder ID. Ärgerlich. Aber Sie wissen, dass es immer direkt nach dem Produkttitel erscheint, und der Titel enthält immer das Wort “Laptop”.

Das ist ein perfekter Fall für die Achse:

Dieser schöne kleine Ausdruck findet zuerst den Titel, der “Laptop” enthält. Von dort navigiert er zum unmittelbar folgenden Geschwisterelement, dessen Klassenattribut price enthält. Diese Art des relationalen Ansteuerns ist ein Grundpfeiler beim Scrapen dynamischer Seiten, ein Thema, das wir in unserem Leitfaden zum Web Scraping mit Selenium und Python ausführlicher behandeln.

Alles zusammenbringen: Praxisbeispiele und Performance-Tuning

Theorie ist das eine, aber diese Funktion in einem echten Projekt einzusetzen, ist der Moment, in dem es ernst wird. Gehen wir durch, wie man diese Konzepte in der Praxis anwendet und, ebenso wichtig, wie man verhindert, dass die Scraper auf komplexen Websites zum Schneckentempo abbremsen.

Nehmen wir an, Sie scrapen Produktdetails von einer E-Commerce-Seite. Die Produkttitel stehen immer in einem Tag, aber die Designer wurden bei den Klassen ein wenig kreativ. Einige sind so, andere wieder anders. Der Preis sitzt immer in einem Element direkt nach dem Titel.

So würden Sie das mit einem schnellen Python-Skript handhaben:

from lxml import html import requests

html_content = """

tree = html.fromstring(html_content)

product_cards = tree.xpath(“//div[contains(@class, product-card )]”)

for card in product_cards:

name = card.xpath(”.//h2[contains(@class, product-title )]/text()”)[0] price = card.xpath(”.//span[contains(@class, price-tag )]/text()”)[0] print(f”Product: {name.strip()}, Price: {price.strip()}”) Das ist ein perfektes Beispiel dafür, wie diese Funktion Ihren Scraper widerstandsfähig gegen kleinere Attributänderungen macht. Sie sehen, wie unverzichtbar das wird, wenn Sie lernen, wie man Daten von LinkedIn scrapt, wo Elementklassen oft lang, komplex und dynamisch generiert sind.

Die versteckten Kosten schlechter XPath-Performance

Diese Funktion ist ein fantastisches Werkzeug, aber sie hat eine Schattenseite. Unbedacht eingesetzt, kann sie zu einem ernsten Performance-Flaschenhals werden. Ein schlecht geschriebener XPath kann die Engine des Browsers zwingen, jedes einzelne Element auf der Seite zu durchsuchen, und das ist ein Rezept für einen sehr, sehr langsamen Scraper.

Der größte Übeltäter ist der Start einer Abfrage mit einer globalen Suche. Ein solcher Ausdruck ist ein Performance-Albtraum. Sie sagen der Engine buchstäblich: “Halt alles an und durchsuche den Text jedes einzelnen Knotens in diesem gesamten Dokument.” Auf einer modernen, JavaScript-lastigen Seite mit Tausenden von Elementen kommt Ihr Scraper zum Stillstand.

Die Lösung besteht darin, der XPath-Engine einen besseren Ausgangspunkt zu geben. Verankern Sie Ihre Suche immer am spezifischsten übergeordneten Element, das Sie finden können.

Einfache Tipps für schnellere Abfragen

Die Verbesserung Ihrer XPath-Performance dreht sich nicht um komplexe Algorithmen; es geht darum, ein paar kluge Entscheidungen zu treffen, die den Suchbereich dramatisch verkleinern. Behalten Sie diese für jeden Scraper im Hinterkopf, den Sie bauen.

  • Globale Suche eliminieren: Beginnen Sie nie mit einer globalen Suche, wenn es sich vermeiden lässt. Werden Sie stattdessen spezifisch. Sehen Sie den Unterschied? Sie sagen der Engine genau, wo sie suchen soll.
  • An einer ID verankern: Der absolut schnellste Weg, ein Element zu finden, ist über seine eindeutige ID. Wenn ein stabiler übergeordneter Container eine ID hat, verwenden Sie sie als Ausgangspunkt für Ihren XPath. Es ist ein direkter, schneller Pfad zu Ihrem Ziel.
  • Von außen nach innen arbeiten: Denken Sie wie das DOM. Finden Sie zuerst ein größeres, stabiles Container-Element, dann suchen Sie innerhalb seiner Kinder nach den Daten, die Sie brauchen. Das ist weit effizienter, als den Browser für jedes einzelne Feld die gesamte Seite von Grund auf durchsuchen zu lassen.

Diese kleinen Anpassungen sorgen dafür, dass Ihre Scraper nicht nur genau, sondern auch schnell genug für große Aufgaben sind. Für weitere übergeordnete Strategien werfen Sie einen Blick in unseren Leitfaden zu Web-Scraping-Best-Practices für Entwickler.

Häufige Fragen zur Verwendung von XPath Contains

Sobald Sie diese Funktion in Ihren Scraping-Projekten einsetzen, werden Sie unweigerlich auf ein paar gängige Hürden stoßen. Diese Fragen tauchen ständig auf, und glücklicherweise sind die Lösungen meist unkompliziert, sobald man die zugrunde liegende Mechanik verstanden hat.

Gehen wir die häufigsten Fallstricke durch und wie man sie wie ein Profi meistert.

Text vs. Punkt: Was ist der wirkliche Unterschied?

Das ist wahrscheinlich die wichtigste Unterscheidung, die man richtig hinbekommen muss. Es ist der Unterschied zwischen einem Scraper, der zuverlässig funktioniert, und einem, der unerwartet kaputtgeht.

Stellen Sie es sich so vor: Die Textfunktion ist extrem wörtlich. Sie betrachtet nur Textknoten, die direkte Kinder des Elements sind, das Sie ansteuern. Wenn irgendein Teil des Textes in einem anderen Tag eingewickelt ist, sieht sie ihn nicht. Sie ist völlig blind für verschachtelten Inhalt.

Andererseits ist der Punkt das, was Sie in 99 % der Fälle verwenden wollen. Der Punkt repräsentiert das aktuelle Element und all seine Nachkommen. Er greift im Wesentlichen den kombinierten, gerenderten Text ab, den Sie auf dem Bildschirm sehen, und ignoriert dabei alle zugrunde liegenden HTML-Tags.

Wie mache ich eine Suche unabhängig von der Groß-/Kleinschreibung?

Es ist ein klassisches Problem: Sie müssen “Product” finden, aber die Seite verwendet vielleicht “product” oder “PRODUCT”. Leider hat XPath 1.0, das Sie in den meisten Browsern und Scraping-Bibliotheken antreffen, keine einfache Funktion dafür.

Die standardmäßige, kampferprobte Lösung ist die Verwendung der translate-Funktion.

Die Idee besteht darin, sowohl den Text, den Sie durchsuchen, als auch Ihren Ziel-Teilstring vor dem Vergleich in dieselbe Schreibweise (üblicherweise Kleinbuchstaben) zu zwingen.

Hier ist das Muster. Es sieht ein wenig sperrig aus, aber es ist der zuverlässigste Weg, sicherzustellen, dass Ihr Scraper nicht allein wegen unvorhersehbarer Groß- und Kleinschreibung versagt.

Kann die Verwendung von Contains meinen Scraper verlangsamen?

Oh, absolut. Wenn unbedacht eingesetzt, kann diese Funktion Ihren Scraper zum Schneckentempo bringen. Die größte Performance-Falle ist der Start eines XPath mit einer globalen Suche. Das weist die Engine an, jedes einzelne Element auf der Seite zu durchsuchen, was auf modernen, komplexen Websites brutal langsam sein kann.

Die Lösung ist einfach: Beginnen Sie Ihren Pfad immer so spezifisch wie möglich. Verankern Sie Ihre Suche, wann immer Sie können, an einem bekannten, stabilen Container.

  • Langsam:
  • Schnell:

Diese eine Änderung kann einen gewaltigen Unterschied machen und den Suchbereich von Tausenden Elementen auf nur eine Handvoll reduzieren. Für jedes ernsthafte Scraping-Projekt ist diese Art der Optimierung nicht verhandelbar.

Wann ist es besser, Starts-With zu verwenden?

Obwohl die contains-Funktion vielseitig ist, ist starts-with für bestimmte Situationen präziser. Sie sollten zu starts-with greifen, wenn Sie wissen, dass der Anfang eines Attributs oder Textes konsistent ist, das Ende aber dynamisch.

Ein perfektes Beispiel aus der Praxis ist ein Element mit einer dynamisch generierten ID, etwa der Reihe nach.

Die Verwendung von starts-with ist viel sauberer und sicherer als die contains-Funktion. Sie eliminiert das Risiko, versehentlich ein anderes Element zu treffen, das zufällig “post-” irgendwo anders in seiner ID stehen hat, und gibt Ihnen einen weit robusteren Selektor.

ScrapeUnblocker kostenlos testen

Über 99 % Erfolgsquote · ab 0,55 € pro 1.000 Aufrufe · 500 kostenlose Anfragen bei der Registrierung.

Kostenlos testen → Preise ansehen