Zurück zum Blog

CSS Selectors Cheat Sheet - Tipps und Tricks zum Scrapen des Webs

CSS Selectors Cheat Sheet - Tipps und Tricks zum Scrapen des Webs

Einführung in das DOM

Beim Parsen einer HTML-Datei erstellt der Browser in seinem Speicher eine Datendarstellung, die wie ein Baum aussieht. Diese Darstellung wird DOM (Document Object Model) genannt. Für jeden HTML-Tag gibt es im DOM einen Knoten, der mit ihm verknüpft ist. Ein Knoten hat Eigenschaften wie Name, Inhalt, Kindknoten, Stile, Ereignisse usw. Weitere Informationen darüber, wie das Browser-Rendering funktioniert, finden Sie in diesem Artikel Wie das Browser-Rendering funktioniert - hinter den Kulissen.

Wenn wir sagen, dass wir auf Daten einer Webseite zugreifen wollen, wollen wir nur durch das DOM zu einer bestimmten Gruppe von Knoten iterieren und den Inhalt darin extrahieren. In diesem Artikel werde ich Ihnen verschiedene Tipps geben, wie Sie mit CSS-Selektoren schnell auf diese Knoten zugreifen können.

Was sind CSS-Selektoren?

Warum heißen sie überhaupt CSS-Selektoren (Cascading Style Sheets)? 

CSS wird verwendet, um das Aussehen von Knoten auf einer Seite zu definieren. Mit CSS können Sie Regeln für das Aussehen eines Knotens und seine Interaktion mit anderen Knoten erstellen. Eine Regel besteht aus einem Selektor und einer Liste von Stilen, die überschrieben werden sollen.

Diese Selektoren werden also mit CSS in Verbindung gebracht, weil dies ihre häufigste Verwendung ist, aber wir müssen sie nicht nur mit CSS verwenden. Mit CSS wollen Sie einen Knoten auswählen und seine Stileigenschaft ändern. Wenn Sie darüber nachdenken, wollen wir das Gleiche tun: einen Knoten auswählen und etwas mit ihm tun, z. B. seinen Inhalt lesen oder ein Ereignis auslösen. 

Wie funktionieren CSS-Selektoren?

Es wird Ihnen sehr helfen, wenn Sie sich die Auswahl vorstellen. Nehmen wir an, Sie wollen alle Absätze von einer Website abrufen. Sie möchten alle Knoten, die den Namen "p" haben, erhalten. Das können Sie von Hand machen. Sie müssen nur jeden Knoten im DOM durchlaufen und nur die Knoten auswählen, die node.tagName === 'P' haben (Tag-Namen werden in Großbuchstaben geschrieben).

Hier ist ein kurzer Codeschnipsel, den Sie verwenden können:

function scrapeByTagName(node, tagName) {
    if (node === null)
        return;
 
    node.childNodes.forEach(node => {
        //console.log(node.tagName)

        if (node.tagName?.toLowerCase() === tagName.toLowerCase()) {
            console.log(node)
            return
        }

        scrapeByTagName(node, tagName)
    });
}

Ich habe eine Dummy-Webseite erstellt, die wie folgt aussieht:

Beispiel für eine Webseitenkarte, die Überschriften und Absätze mit IDs und CSS-Klassen wie .text und .bold zeigt

Und hier ist der HTML-Code dafür:

<!DOCTYPE html>
<html lang="en">

<head>
    <link rel="stylesheet" href="styles.css">
    <script src="script.js"></script>
</head>

<body>
    <div id="wrapper">
        <h1 custom-attr="some data">Some Title</h1>
        <h2 custom-attr="some other data">Some Subtitle</h2>
        <div id="container">
            <p custom-attr>paragraph
                <span> subparagraph</span>
            </p>
            <p id="text">paragraph with id #text</p>
            <p class="bold">paragraph with class .bold</p>
            <p class="text">paragraph with class .text</p>
            <p class="text bold">paragraph with class .text.bold</p>
            <p class="text italic">paragraph with class .text.italic</p>
        </div>
    </div>
</body>

</html>

Nachdem ich die Funktion in der Browserkonsole ausgeführt hatte, erhielt ich diese Antwort:

Code snippet showing HTML <p> elements with id and class attributes under a function call scrapeByTagName(document, 'p')

Wie Sie sehen können, hat die Funktion alle p-Tags aufgezeichnet.

Um die Browserkonsole anzuzeigen, musst du die Entwicklertools öffnen und zum Reiter „Konsole“ wechseln oder Strg+E. Du kannst devTools öffnen, indem du mit der rechten Maustaste auf ein Element klickst und „Inspect“„Inspect“ aus dem Menü oder über die Tastenkombination Strg + Umschalt + i.

Wie benutzt man CSS-Selektoren?

Wir werden zwei Methoden verwenden: querySelector und querySelectorAll. Diese Methoden sind bei jedem Objekt vom Typ Element vorhanden. Die Knoten, die wir scrapen möchten, haben den Typ HTMLElement, der vom Typ Element abgeleitet ist.

querySelector gibt den ersten Knoten zurück, der dem Selektor entspricht. querySelectorAll gibt eine Liste mit allen Knoten zurück, die dem Selektor entsprechen. Um das zuvor gezeigte Beispiel nachzubilden, müssen wir lediglich querySelectorAll aufrufen und die zurückgegebene Liste durchlaufen.

document.querySelectorAll('p').forEach(node => console.log(node))
JavaScript-Konsolen-Snippet, das mit `document.querySelectorAll('p')` Absatzelemente mit verschiedenen Klassen und IDs protokolliert

Wie du sehen kannst, habe ich document.querySelectorrAll verwendet habe, das liegt daran, dass document im Fensterkontext als Stamm der Webseite definiert ist, also als Entsprechung des HTML-Tags. Sie können querySelector-Methoden mit jedem Knoten verwenden, nicht nur mit dem Stammknoten.

Um tatsächlich etwas zu scrapen, müssen Sie eine Bibliothek verwenden, die ein Browserfenster öffnen und eine URL aufrufen kann. Erst dann wird Ihr Code im Kontext dieses Fensters ausgeführt. Um mehr darüber zu erfahren, wie man das macht, empfehle ich diesen Artikel The Ultimate Guide to Web Scraping with JavaScript and Node.Js.

Hier bei WebScrapingAPI verwenden wir Puppeteer. Puppeteer ist eine Bibliothek, mit der wir Instanzen von Chromium-Browsern ohne Kopf steuern können. Sie können unsere API verwenden, um Daten aus einer Website zu extrahieren, ohne einen eigenen Scraper zu erstellen. Wir haben einen Parameter namens extract_rules, der CSS-Selektoren verwendet, um Daten aus einer bestimmten URL zu extrahieren.

Der CSS-Selektoren-Spickzettel

Der *-Selektor

Dieser Selektor gibt alle Elemente der Baumstruktur an. Er wird zwar nicht häufig verwendet, ist aber gut zu wissen.

Der Selektor .class

Sie können einen Knoten mit einer bestimmten Klasse erhalten, indem Sie .class verwenden. Dies wird meist verwendet, wenn Sie eine Liste von Elementen haben. Da die Elemente in einer Liste wahrscheinlich gleich aussehen, können sie die gleiche Klasse haben. Lassen Sie uns nach der Klasse .text suchen.

Codeausschnitt, der `document.querySelectorAll('.text')` verwendet, um Elemente zu durchlaufen, mit Beispiel-Absatz-Tags

Vielleicht möchten Sie den Knoten auswählen, der die Klasse .bold hat.

Beispiel für die JavaScript-Konsole: Auswahl von Elementen mit der Klasse „.bold“ und Protokollierung von zwei Absatzknoten

Es sieht so aus, als gäbe es ein weiteres Element, das die Klasse .bold hat. Sie können mit dem Klassenselektor spezifischer sein, indem Sie mehrere verkettete Klassen verwenden.

Beispiel für die JavaScript-Konsole: Auswahl von „.text.bold“ und Protokollierung eines Absatzelements mit den Klassen „text“ und „bold“

Bitte beachten Sie, dass zwischen den Kursen keine Lücken bestehen.

document.querySelectorAll('.text .bold').forEach(node => console.log(node))

Diese Abfrage gibt nichts aus dem obigen HTML zurück, da sie nach einem Element mit der Klasse .text sucht, das ein untergeordnetes Element mit der Klasse .bold hat (nicht unbedingt ein direktes untergeordnetes Element). Die Abfrage würde das untergeordnete Element zurückgeben, wenn es gefunden wird. 

Der Selektor #id

Was ist, wenn ein Element keine Klasse hat oder wenn die Klasse zu häufig im Dokument verwendet wird? Sie können das ID-Attribut verwenden, um einen höheren Grad an Spezifität zu erreichen. Der Nachteil der Verwendung des id-Selektors ist, dass die id in den meisten Fällen in der HTML-Seite eindeutig ist, so dass Sie keine Liste von Knoten mit ihr erhalten können.

Codeausschnitt, der mit `document.querySelector('#text')` ein Absatzelement mit der ID „text“ zurückgibt

Der Knotennamen-Selektor

Jeder Knoten hat einen Namen. Das ist der genaue Name des gepaarten Tags im HTML. Sie können alle Knoten mit einem bestimmten Namen erhalten, indem Sie ihren Namen im Selektor verwenden.

JavaScript console output listing two <div> elements with ids wrapper and container

Der [Attribut]-Selektor 

Es kann vorkommen, dass Sie alle Knoten auswählen möchten, die ein bestimmtes Attribut aufweisen.

Beispiel in der JavaScript-Konsole zur Auswahl von Elementen mit einem „custom-attr“-Attribut, wobei Überschriften- und Absatzknoten angezeigt werden

Sie können auch den Wert des Attributs angeben.

Beispiel für die JavaScript-Konsole: Auswahl von [custom-attr="some data"], Rückgabe eines einzelnen h1-Elements

Oder auch, was der Attributwert enthalten soll. Sie können die Tilde ~ vor dem Gleichheitszeichen verwenden, um festzulegen, dass der Attributwert eine Liste von Wörtern enthalten soll.

Beispiel für die JavaScript-Konsole zur Auswahl von [custom-attr~="data"], wobei h1- und h2-Elemente mit benutzerdefinierten Attributen abgeglichen werden

Der Attributselektor wird am häufigsten verwendet, wenn Sie sich entscheiden, einen Scrapper zu erstellen. Er ist sehr mächtig und hat viel mehr Anwendungsfälle als das, was ich hier gezeigt habe. Weitere Informationen über die Verwendung des Attributselektors finden Sie hier W3 Attributselektoren.

Gruppierung mehrerer Selektoren

Ermittlung aller p-Knoten, die eine ID haben.

Beispiel für die JavaScript-Konsole zur Auswahl von p[id], das ein Absatzelement mit der ID „text“ zurückgibt

Wählen Sie alle Spannenknoten aus, die untergeordnet zu einem p-Knoten sind.

Beispiel für die JavaScript-Konsole zur Auswahl von `p` und `span`, das ein `span`-Element innerhalb eines Absatzes zurückgibt

Ermittelt alle Div-Knoten, die direkte Kindknoten des Body-Knotens sind.

Beispiel für die JavaScript-Konsole: Auswahl von „body > div“ und Rückgabe eines umschließenden „div“-Elements

Alle p-Knoten mit der Klasse .text ermitteln

Beispiel für die JavaScript-Konsole zur Auswahl von `p.text`, das Absatzelemente mit der Klasse „text“ in den Varianten „normal“, „bold“ und „italic“ zurückgibt

Die Möglichkeiten der Gruppierung dieser Selektoren sind endlos. Versuchen Sie, den HTML-Code von oben zu kopieren und weitere Knoten hinzuzufügen. Probieren Sie dann verschiedene Kombinationen von Selektoren aus. Wenn Sie mehr über CSS-Selektoren im Allgemeinen erfahren möchten, bietet Mozilla einen fantastischen Artikel, der erklärt , wie CSS-Selektoren für die Webentwicklung funktionieren.

Zusammenfassung

Wenn Sie etwas Neues lernen wollen, rate ich Ihnen, zuerst zu lernen, wie die Sache funktioniert. Ja, das ist ein optionaler Schritt, aber er wird dir einige Informationen geben, die andere nicht haben. 

Im Bereich der Softwareentwicklung helfen Ihnen diese Informationen bei der Suche nach der richtigen Antwort auf Ihr Problem/Ihren Fehler. Sie können die Sache selbst in die Hand nehmen und sogar eine eigene Lösung entwickeln.

Wenn Sie CSS-Selektoren wirklich verstehen wollen, müssen Sie das DOM verstehen. Es ist einfach ein Baum (ein verbundener azyklischer ungerichteter Graph) mit Knoten, die einen Namen und einige Attribute haben. Das war's. Wenn Sie einen Selektor schreiben, schreiben Sie einfach einen String, der geparst und zur Abfrage des DOM verwendet wird.

Über den Autor
Ștefan Răcilă, Full-Stack-Entwickler bei WebScrapingAPI
Ștefan RăcilăFull-Stack-Entwickler

Stefan Racila ist DevOps- und Full-Stack-Entwickler bei WebScrapingAPI, wo er Produktfunktionen entwickelt und die Infrastruktur wartet, die für die Zuverlässigkeit der Plattform sorgt.

Los geht’s

Sind Sie bereit, Ihre Datenerfassung zu erweitern?

Schließen Sie sich den über 2.000 Unternehmen an, die WebScrapingAPI nutzen, um Webdaten im Unternehmensmaßstab ohne zusätzlichen Infrastrukturaufwand zu extrahieren.