Zurück zum Blog
Anleitungen
Sorin-Gabriel MaricaLast updated on Mar 31, 20268 min read

Der ultimative Leitfaden für den Einstieg in das Web-Scraping mit Go

Der ultimative Leitfaden für den Einstieg in das Web-Scraping mit Go

Web-Scraping mit Go ist eine hervorragende Möglichkeit, einen schnellen und leistungsstarken Scraper zu erstellen. Das liegt daran, dass Go eine der besten Programmiersprachen für die parallele Programmierung ist. Bevor wir jedoch direkt loslegen, möchte ich Ihnen zunächst näher erläutern, was Web-Scraping ist und wie es Ihnen helfen kann.

Web-Scraping ist der Prozess der Datenextraktion aus Websites. Dieser Vorgang kann manuell durchgeführt werden, doch dieser Ansatz ist bei großen Datenmengen nicht empfehlenswert. In diesem Artikel werden wir untersuchen, wie Sie mit Go Ihren eigenen automatisierten Web-Scraper von Grund auf erstellen können.

Wenn Sie neu auf diesem Gebiet sind, fragen Sie sich vielleicht, welche Anwendungsfälle Web Scraping bietet. Hier ist eine kleine Liste mit einigen der gängigsten:

  • Preisvergleichstools – Mit einem Web-Scraper lassen sich viele Tools erstellen. Eines der gängigsten und nützlichsten ist ein Preisvergleichstool. Ein solches Tool würde die Preise für ein Produkt aus vielen Quellen scrapen und das bestmögliche Angebot anzeigen.
  • Maschinelles Lernen – Wenn Sie ein Modell mithilfe von maschinellem Lernen erstellen möchten, benötigen Sie einen Trainingsdatensatz. Manchmal finden Sie zwar bereits vorhandene Datensätze, die Sie verwenden können, doch oft müssen Sie zusätzliche Arbeit investieren und die benötigten Daten selbst beschaffen.
  • Marktforschung – Ein dritter Anwendungsfall ist das Scrapen von Informationen aus dem Internet, um herauszufinden, wer Ihre Konkurrenten sind und was diese tun. Auf diese Weise können Sie mit der Konkurrenz Schritt halten oder ihr sogar einen Schritt voraus sein, indem Sie über alle neuen Funktionen informiert sind, die diese möglicherweise hinzugefügt hat.

Was Sie für das Scraping von Daten mit Go benötigen

Bevor wir beginnen, musst du GoLang-Code auf deinem Rechner ausführen können. Dazu musst du lediglich Go installieren, falls du dies noch nicht getan hast. Weitere Details zur Installation von Go und zur Überprüfung, ob es bereits installiert ist, findest du hier.

Außerdem benötigen Sie eine IDE oder einen Texteditor Ihrer Wahl, in dem wir den Code schreiben werden. Ich bevorzuge Visual Studio Code, aber Sie können gerne das verwenden, was Ihnen am besten gefällt.

Das war’s schon. Ziemlich einfach, oder? Kommen wir nun zum Hauptthema dieses Artikels: Web-Scraping mit Go.

Erstellen eines Web-Scrapers mit Go

Um unseren Scraper zu erstellen, benötigen wir zunächst ein Ziel, also einen Datensatz, den wir aus einer bestimmten Quelle sammeln möchten. Als Thema für unseren Scraper habe ich daher das Scraping der wöchentlichen Downloads der ersten Pakete von npmjs.com gewählt, die das Schlüsselwort „framework“ verwenden. Sie finden diese auf dieser Seite: https://www.npmjs.com/search?q=keywords:framework&page=0&ranking=optimal)

Untersuche den Inhalt der Seite, die du scrapen möchtest

Um das Scraping richtig durchzuführen, müssen Sie, bevor Sie mit der eigentlichen Datenextraktion beginnen, herausfinden, wo sich die Daten befinden. Damit meine ich, dass Sie die HTML-Selektoren erstellen müssen, um die Daten abzufragen, basierend auf der HTML-Struktur der Seite.

Um die HTML-Struktur der Seite anzuzeigen, können Sie die Entwicklertools nutzen, die in den meisten modernen Browsern verfügbar sind. In Chrome können Sie dies auf der Seite tun, indem Sie mit der rechten Maustaste auf das Element klicken, das Sie extrahieren möchten, und dann auf „Seite untersuchen“ klicken. Sobald Sie das getan haben, sehen Sie etwa Folgendes:

Anhand des HTML-Codes, den Sie auf der rechten Seite (im Inspektionsfenster) sehen, können wir nun die Selektoren erstellen, die wir verwenden werden. Von dieser Seite benötigen wir lediglich die URLs der einzelnen Pakete.

Ein Blick auf den HTML-Code zeigt, dass die von der Website verwendeten CSS-Klassen programmgesteuert generiert werden. Da sie sich daher nicht zuverlässig zum Scraping eignen, verwenden wir stattdessen die HTML-Tags. Auf der Seite sehen wir, dass die Pakete in <section>-Tags stehen und dass sich der Link zum Paket im ersten div des ersten div des Abschnitts befindet.

Mit diesem Wissen können wir den folgenden Selektor erstellen, um die Links aller Pakete zu extrahieren: section > div:first-child > div:first-child a. Bevor wir ihn im Code ausprobieren, können wir den Selektor über die Entwicklertools des Browsers testen. Gehen Sie dazu auf die Registerkarte „Konsole“ und führen Sie document.querySelectorAll("{{ SELECTOR }}") aus:

Wenn wir mit der Maus über jedes der zurückgegebenen Elemente der Knotenliste fahren, sehen wir, dass es sich genau um die Elemente handelt, nach denen wir gesucht haben, und somit können wir diesen Selektor verwenden.

Eine Seite mit Go scrapen

Endlich beginnen wir mit der Erstellung des Scrapers! Dazu sollten Sie zunächst einen Ordner erstellen, in dem wir unseren gesamten Code ablegen. Als Nächstes müssen Sie ein Terminalfenster öffnen, entweder über Ihre IDE oder über Ihr Betriebssystem, und zu unserem Ordner wechseln.

Um ein Terminal in diesem Ordner zu öffnen, klicken Sie in Visual Studio Code auf „Terminal“ -> „New Terminal“ (in der oberen Leiste).

Nachdem wir nun unser Terminal geöffnet haben, ist es an der Zeit, das Projekt zu initialisieren. Dies kannst du tun, indem du den folgenden Befehl ausführst:

go mod init webscrapingapi.com/my-go-scraper

Dadurch wird in Ihrem Ordner eine Datei namens go.mod mit folgendem Inhalt erstellt:

module webscrapingapi.com/my-go-scraper
go 1.19

Um die Anfrage an die Seite zu stellen und die Selektoren aus dem HTML zu extrahieren, verwenden wir Colly, ein GoLang-Paket (weitere Informationen finden Sie in der Colly-Dokumentation). Um dieses Paket zu installieren, müssen Sie folgenden Befehl ausführen

go get github.com/gocolly/colly

Nachdem nun alles vorbereitet ist, müssen wir nur noch unsere Datei „main.go“ erstellen und etwas Code schreiben. Der Code zum Extrahieren aller Links von der ersten Seite der npmjs-Frameworks lautet wie folgt:

package main

import (
    "fmt"
    "github.com/gocolly/colly"
)

func scrape() {
    c := colly.NewCollector()

    // Find and print all links
    c.OnHTML("section > div:first-child > div:first-child a", func(e *colly.HTMLElement) {
        fmt.Println(e.Attr("href"))
    })
    c.Visit("https://www.npmjs.com/search?q=keywords:framework&page=0&ranking=optimal")
}

func main() {
    scrape()
}

Falls dies auf den ersten Blick schwer verständlich erscheint, keine Sorge – wir werden es in den folgenden Abschnitten aufschlüsseln und erklären. 

Jede GoLang-Datei sollte mit dem Paketnamen und den Importen beginnen, die Go verwenden wird. In diesem Fall sind die beiden Pakete, die wir verwenden, „fmt“ zum Ausgeben der von uns gescrapten Links und „Colly“ (für das eigentliche Scraping).

Im nächsten Teil haben wir die Funktion `scrape()` erstellt, die sich um das Scraping der benötigten Links kümmert. Dazu besucht die Funktion die erste Seite und wartet darauf, den von uns festgelegten Selektor zu finden. Wenn ein Element dieses Selektors erscheint, fährt sie fort und gibt das `href`-Attribut dieses Elements aus.

Der letzte Teil ist die Hauptfunktion, die jedes Mal aufgerufen wird, wenn wir ein Go-Skript ausführen. Um den obigen Code auszuführen, gib im Terminal „go run main.go“ ein; du solltest die folgende Ausgabe erhalten:

Wie du sehen kannst, enthält das href-Attribut relative Pfade zu den Links, daher müssen wir die npmjs-URL voranstellen.

Nutzen Sie die Parallelität von GoLang für mehr Effizienz

Eine der coolsten Funktionen von GoLang sind die GoRoutines. GoRoutines sind einfache, leichtgewichtige Threads, die von der Go-Laufzeitumgebung verwaltet werden. Das Tolle daran ist, dass Go uns dabei helfen kann, viele URLs gleichzeitig blitzschnell zu scrapen.

Zuvor haben wir die Links für die ersten 20 Pakete unter dem Stichwort „framework“ auf npmjs.com extrahiert. Nun werden wir versuchen, alle diese Links gleichzeitig zu scrapen und die wöchentlichen Downloadzahlen für jeden einzelnen zu extrahieren. Dazu verwenden wir GoRoutines und WaitGroups.

Hier ist der endgültige Code zum Extrahieren der wöchentlichen Downloads mithilfe der Goroutines:

package main

import (
    "fmt"
    "github.com/gocolly/colly"
    "sync"
)

func scrapeWeeklyDownloads(url string, wg *sync.WaitGroup) {
    defer wg.Done()

    c := colly.NewCollector()

    // Find and print the weekly downloads value
    c.OnHTML("main > div > div:last-child > div:not([class]) p", func(e *colly.HTMLElement) {
        fmt.Println(fmt.Sprintf("%s - %s", url, e.Text))
    })
    c.Visit(url)
}

func scrape() {
    c := colly.NewCollector()

    var wg sync.WaitGroup

    // Find and print all links
    c.OnHTML("section > div:first-child > div:first-child a", func(e *colly.HTMLElement) {
        wg.Add(1)
        go scrapeWeeklyDownloads(fmt.Sprintf("%s%s", "https://www.npmjs.com", e.Attr("href")), &wg)
    })
    c.Visit("https://www.npmjs.com/search?q=keywords:framework&page=0&ranking=optimal")

    wg.Wait()
}

func main() {
    scrape()
}

Lassen Sie uns nun besprechen, was unserem vorherigen Code hinzugefügt wurde. Zunächst werden Sie feststellen, dass wir ein neues Paket namens „sync“ importiert haben. Dies hilft uns, GoRoutinen zu verwenden und darauf zu warten, dass die Threads fertig sind, bevor die Ausführung des Programms gestoppt wird.

Als Nächstes wurde die neue Funktion „scrapeWeeklyDownloads“ hinzugefügt. Diese Funktion akzeptiert zwei Parameter: die URL des Links, den wir scrapen wollen, und einen WaitGroup-Zeiger. Diese Funktion ruft die angegebene URL auf und extrahiert die wöchentlichen Downloads (unter Verwendung des Selektors main > div > div:last-child > div:not([class]) p).

Die letzten Änderungen, die Ihnen auffallen werden, befinden sich in der scrape-Funktion, wo wir mit var wg sync.WaitGroup eine WaitGroup erstellt haben. Hier haben wir für jeden Link auf der Paketseite wg.Add(1) verwendet und anschließend eine GoRoutine erstellt, die die Funktion scrapeWeeklyDownloads aufruft. Am Ende der Funktion sorgt die Anweisung wg.Wait() dafür, dass der Code wartet, bis alle GoRoutinen ihre Ausführung beendet haben. 

Weitere Informationen zu WaitGroups finden Sie in diesem Beispiel von golang

Warum GoRoutines und WaitGroups?

Durch die Nutzung von Parallelität in Go mit GoRoutines und WaitGroups können wir einen sehr schnellen Scraper erstellen. Die Ausführung des vorherigen Codebeispiels gibt die Seite und die wöchentlichen Downloadzahlen jedes Pakets zurück. Da wir jedoch Multithreading verwenden, ist die Reihenfolge, in der diese Informationen angezeigt werden, unbekannt (da Threads mit unterschiedlichen Geschwindigkeiten ausgeführt werden).

Wenn Sie den Code unter Linux oder dem Windows Subsystem for Linux (WSL) ausführen, können Sie mit `time go run main.go` die Ausführungszeit des gesamten Skripts anzeigen. Bei mir liegt die Ausführungszeit bei etwa 5 bis 6 Sekunden. Das ist sehr schnell, wenn man bedenkt, dass wir 21 Seiten scrapen (zuerst die Seite mit den Paketen und dann die Seiten der einzelnen Pakete).

Weitere Hindernisse

Die meisten Scraper verlassen sich in der Regel darauf, eine einfache HTTP-Anfrage an die Seite zu stellen, um die benötigten Inhalte zu erhalten. Diese Lösung ist gut, aber manchmal zeigen Websites ihre Informationen über JavaScript-Rendering an. Das bedeutet, dass die Website Ihnen zunächst nur einen Teil ihres Inhalts anzeigt und den Rest dynamisch über JavaScript lädt.

Um solche Seiten zu scrapen, müssen Sie ChromeDriver verwenden und einen echten Chrome-Browser steuern. Es gibt zwar einige Möglichkeiten, dies in Golang zu tun, doch müssen Sie sich zu diesem Thema noch etwas genauer informieren.

Selbst wenn das JavaScript-Rendering abgedeckt ist, gibt es beim Scraping einer Website noch einige zusätzliche Hindernisse. Manche Websites nutzen möglicherweise Anti-Bot-Erkennung, IP-Sperren oder Captchas, um Bots daran zu hindern, ihre Inhalte zu scrapen. Um diese Websites dennoch zu scrapen, kannst du versuchen, einige Tipps und Tricks für das Web-Scraping anzuwenden, wie zum Beispiel deinen Scraper langsamer zu machen und ihn menschlicher agieren zu lassen.

Wenn Sie Ihren Scraper jedoch schnell halten und diese Hindernisse auf einfache Weise umgehen möchten, können Sie WebScrapingAPI nutzen. WebScrapingAPI ist eine API, die Ihnen beim Scraping hilft, indem sie Ihre IP-Adresse wechselt und Anti-Bot-Erkennungen umgeht. Auf diese Weise können Sie weiterhin die blitzschnelle Geschwindigkeit von GoLang nutzen und Ihre Daten im Handumdrehen scrapen.

Fazit zum Web-Scraping mit Go

Web-Scraping ist eine elegante und schnelle Methode, um Daten aus dem Internet zu extrahieren, und es kann für viele verschiedene Anwendungsfälle genutzt werden. Sie können Daten für Ihr Machine-Learning-Modell extrahieren oder mit den gescrapten Daten eine Anwendung von Grund auf neu erstellen.

GoLang ist eine der besten Lösungen auf dem Markt, wenn es um Parallelität geht. Mit GoLang und Colly können Sie einen schnellen Scraper erstellen, der Ihre Daten im Handumdrehen bereitstellt. Dies macht das Web-Scraping mit Go sehr einfach und effizient, sobald Sie sich an die Syntax von Go gewöhnt haben.

Über den Autor
Sorin-Gabriel Marica, Full-Stack-Entwickler @ WebScrapingAPI
Sorin-Gabriel MaricaFull-Stack-Entwickler

Sorin Marica ist Full-Stack- und DevOps-Entwickler bei WebScrapingAPI, wo er Produktfunktionen entwickelt und die Infrastruktur wartet, die für einen reibungslosen Betrieb 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.