Zurück zum Blog
Anleitungen
Raluca PenciucLast updated on Mar 31, 202612 min read

Der ultimative Leitfaden zum Web-Scraping mit C++

Der ultimative Leitfaden zum Web-Scraping mit C++

Vor zwei Millionen Jahren kam einer Gruppe von Höhlenmenschen die Idee, dass ein Stein an einem Stock nützlich sein könnte. Von da an geriet die Sache nur ein wenig außer Kontrolle. Heute geht es bei unseren Problemen weniger darum, vor Säbelzahn-Tigern zu fliehen, sondern eher darum, dass Teamkollegen ihre Commits „did sutff“ nennen.

Die Schwierigkeiten haben sich zwar geändert, aber unsere Besessenheit, Werkzeuge zu entwickeln, um sie zu überwinden, ist geblieben. Web-Scraper sind ein Beweis dafür. Es sind digitale Werkzeuge, die dazu dienen, digitale Probleme zu lösen.

Heute werden wir ein neues Tool von Grund auf neu entwickeln, aber statt Steinen und Stöcken verwenden wir C++, was wohl noch schwieriger ist. Bleibt also dran, um zu erfahren, wie man einen C++-Web-Scraper erstellt und wie man ihn einsetzt!

Web-Scraping verstehen

Unabhängig davon, für welche Programmiersprache du dich entscheidest, musst du verstehen, wie Web-Scraper funktionieren. Dieses Wissen ist entscheidend, um das Skript zu schreiben und am Ende ein funktionsfähiges Tool zu erhalten.

Die Vorteile von Web-Scraping

Es ist nicht schwer vorstellbar, dass ein Bot, der die gesamte Recherche für dich übernimmt, viel besser ist, als Informationen von Hand zu kopieren. Die Vorteile wachsen exponentiell, wenn du große Datenmengen benötigst. Wenn du beispielsweise einen Algorithmus für maschinelles Lernen trainierst, kann dir ein Web-Scraper Monate an Arbeit ersparen.

Der Übersichtlichkeit halber gehen wir alle Vorteile durch, die Web-Scraper Ihnen bieten:

  • Weniger Zeitaufwand für mühsame Arbeit – dies ist der offensichtlichste Vorteil. Scraper extrahieren Daten so schnell, wie Ihr Browser die Seite laden würde. Geben Sie dem Bot eine Liste von URLs, und Sie erhalten sofort deren Inhalt.
  • Erzielen Sie eine höhere Datengenauigkeit – menschliche Arbeit führt unweigerlich zu menschlichen Fehlern. Im Vergleich dazu ruft der Bot immer alle Informationen genau so ab, wie sie dargestellt werden, und wertet sie gemäß Ihren Anweisungen aus.
  • Sorgen Sie für eine gut organisierte Datenbank – je mehr Daten Sie sammeln, desto schwieriger kann es werden, den Überblick zu behalten. Der Scraper ruft nicht nur Inhalte ab, sondern speichert sie auch in dem Format, das Ihnen die Arbeit erleichtert.
  • Nutzen Sie aktuelle Informationen – in vielen Situationen ändern sich Daten von einem Tag auf den anderen. Schauen Sie sich zum Beispiel die Börsenkurse oder Angebote in Online-Shops an. Mit wenigen Zeilen Code kann Ihr Bot dieselben Seiten in festgelegten Intervallen scrapen und Ihre Datenbank mit den neuesten Informationen aktualisieren.

WebScrapingAPI wurde entwickelt, um Ihnen all diese Vorteile zu bieten und gleichzeitig die verschiedenen Hindernisse zu umgehen, auf die Scraper im Web häufig stoßen. Das klingt alles großartig, aber wie lässt sich das in konkrete Projekte umsetzen?

Anwendungsfälle für Web Scraping

Es gibt viele verschiedene Möglichkeiten, Web-Scraper einzusetzen. Die Möglichkeiten sind schier unbegrenzt! Dennoch sind einige Anwendungsfälle häufiger als andere.

Schauen wir uns die einzelnen Situationen genauer an:

  • Suchmaschinenoptimierung – Das Scraping von Suchergebnisseiten nach Ihren Keywords ist eine einfache und schnelle Methode, um festzustellen, wen Sie im Ranking übertreffen müssen und welche Art von Inhalten Ihnen dabei helfen kann.
  • Marktforschung – Nachdem Sie überprüft haben, wie Ihre Konkurrenten in den Suchergebnissen abschneiden, können Sie einen Schritt weiter gehen und deren gesamte digitale Präsenz analysieren. Nutzen Sie den Web-Scraper, um zu sehen, wie sie PPC einsetzen, ihre Produkte beschreiben, welche Preismodelle sie verwenden und so weiter. Im Grunde stehen Ihnen alle öffentlich zugänglichen Informationen zur Verfügung.
  • Markenschutz — Da draußen wird über Ihre Marke gesprochen. Im Idealfall sind es nur positive Dinge, aber das ist keine Garantie. Ein Bot ist bestens dafür ausgerüstet, Bewertungsseiten und Social-Media-Plattformen zu durchsuchen und Ihnen zu melden, wann immer Ihre Marke erwähnt wird. Was auch immer gesagt wird, Sie sind bereit, die Interessen Ihrer Marke zu vertreten.
  • Lead-Generierung – Die Lücke zwischen Ihrem Vertriebsteam und potenziellen Kunden im Internet zu schließen, ist selten einfach. Nun, es wird um einiges einfacher, sobald Sie einen Web-Scraping-Bot einsetzen, um Kontaktinformationen in Online-Unternehmensverzeichnissen wie den Gelben Seiten oder LinkedIn zu sammeln.
  • Content-Marketing – Die Erstellung hochwertiger Inhalte ist zweifellos mit viel Arbeit verbunden. Sie müssen nicht nur glaubwürdige Quellen und eine Fülle von Informationen finden, sondern auch den Ton und den Ansatz erlernen, den Ihr Publikum schätzt. Glücklicherweise werden diese Schritte zur Nebensache, wenn Sie einen Bot haben, der die schwere Arbeit übernimmt.

Es gibt noch viele weitere Beispiele. Natürlich könntest du auch eine völlig neue Methode entwickeln, um die Datenextraktion zu deinem Vorteil zu nutzen. Wir fördern stets den kreativen Einsatz unserer API.

Die Herausforderungen des Web-Scrapings

So wertvoll Web-Scraper auch sind, es ist nicht alles eitel Sonnenschein. Manche Websites mögen es nicht, von Bots besucht zu werden. Es ist nicht schwer, Ihren Scraper so zu programmieren, dass er die besuchte Website nicht übermäßig belastet, aber deren Wachsamkeit gegenüber Bots ist berechtigt. Schließlich kann die Website möglicherweise nicht zwischen einem gut erzogenen und einem böswilligen Bot unterscheiden.

Infolgedessen gibt es einige Herausforderungen, auf die Scraper bei ihrer Arbeit stoßen.

Die problematischsten Hürden sind:

  • IP-Sperren – Es gibt verschiedene Möglichkeiten, festzustellen, ob ein Besucher ein Mensch oder eine Maschine ist. Die Vorgehensweise nach der Identifizierung eines Bots ist jedoch viel einfacher: IP-Sperrung. Auch wenn dies bei Einhaltung der notwendigen Vorsichtsmaßnahmen selten vorkommt, ist es dennoch ratsam, einen Proxy-Pool bereitzuhalten, damit Sie auch dann weiter Daten extrahieren können, wenn eine IP gesperrt wird.
  • Browser-Fingerprinting – Jede Anfrage, die Sie an eine Website senden, verrät auch einige Ihrer Informationen. Die IP-Adresse ist das häufigste Beispiel, aber Anfrage-Header geben der Website auch Auskunft über Ihr Betriebssystem, Ihren Browser und andere kleine Details. Wenn eine Website diese Informationen nutzt, um festzustellen, wer die Anfragen sendet, und erkennt, dass Sie viel schneller browsen, als es ein Mensch tun sollte, müssen Sie damit rechnen, umgehend gesperrt zu werden.
  • Javascript-Rendering — Die meisten modernen Websites sind dynamisch. Das heißt, sie verwenden Javascript-Code, um Seiten für den Nutzer anzupassen und ein individuelleres Erlebnis zu bieten. Das Problem ist, dass einfache Bots an diesem Code hängen bleiben, da sie ihn nicht ausführen können. Das Ergebnis: Der Scraper ruft Javascript ab, anstatt des beabsichtigten HTML-Codes, der relevante Informationen enthält.
  • Captchas – Wenn Websites nicht sicher sind, ob ein Besucher ein Mensch oder ein Bot ist, leiten sie ihn auf eine Captcha-Seite weiter. Für uns ist das bestenfalls ein kleines Ärgernis, für Bots jedoch meist ein völliger Stillstand – es sei denn, sie verfügen über Skripte zum Lösen von Captchas.
  • Anfragedrosselung – Der einfachste Weg, um zu verhindern, dass Besucher den Server der Website überlasten, besteht darin, die Anzahl der Anfragen zu begrenzen, die eine einzelne IP-Adresse innerhalb eines festgelegten Zeitraums senden kann. Sobald diese Anzahl erreicht ist, muss der Scraper möglicherweise die Wartezeit abwarten oder ein Captcha lösen. So oder so ist das nicht gut für Ihr Datenextraktionsprojekt.

Das Web verstehen

Wenn Sie einen Web-Scraper erstellen möchten, sollten Sie einige Schlüsselkonzepte der Funktionsweise des Internets kennen. Schließlich nutzt Ihr Bot das Internet nicht nur zum Sammeln von Daten, sondern muss sich auch unter die anderen Milliarden von Nutzern mischen.

Wir stellen uns Websites gerne wie Bücher vor, und das Lesen einer Seite bedeutet nur, zur richtigen Seite zu blättern und hinzuschauen. In Wirklichkeit ähnelt es eher Telegrammen, die zwischen dir und dem Buch ausgetauscht werden. Du forderst eine Seite an, und sie wird dir gesendet. Dann bestellst du die nächste, und dasselbe passiert.

Dieses Hin und Her erfolgt über HTTP, das Hypertext Transfer Protocol. Damit du als Besucher eine Seite sehen kannst, sendet dein Browser eine HTTP-Anfrage und erhält eine HTTP-Antwort vom Server. Der gewünschte Inhalt ist in dieser Antwort enthalten.

HTTP-Anfragen bestehen aus vier Komponenten:

  • Die URL (Uniform Resource Locator) ist die Adresse, an die Sie Anfragen senden. Sie führt zu einer eindeutigen Ressource, die eine ganze Webseite, eine einzelne Datei oder alles dazwischen sein kann.
  • Die Methode gibt an, welche Aktion Sie ausführen möchten. Die gängigste Methode ist GET, die Daten vom Server abruft. Hier finden Sie eine Liste der gängigsten Methoden.
  • Die Header sind Metadaten, die Ihrer Anfrage Gestalt geben. Wenn Sie beispielsweise ein Passwort oder Anmeldedaten angeben müssen, um auf Daten zuzugreifen, werden diese in einem speziellen Header übermittelt. Wenn Sie Daten speziell im JSON-Format erhalten möchten, geben Sie dies in einem Header an. User-Agent ist einer der bekanntesten Header beim Web-Scraping, da Websites ihn nutzen, um Besucher zu identifizieren.
  • Der Body ist der allgemeine Teil der Anfrage, in dem Daten gespeichert werden. Wenn Sie Inhalte abrufen, ist dieser wahrscheinlich leer. Wenn Sie hingegen Informationen an den Server senden möchten, finden sich diese hier.

Nach dem Absenden der Anfrage erhalten Sie eine Antwort, auch wenn die Anfrage keine Daten erhalten hat. Die Struktur sieht wie folgt aus:

  • Der Statuscode ist ein dreistelliger Code, der dir auf einen Blick sagt, was passiert ist. Kurz gesagt bedeutet ein Code, der mit „2“ beginnt, in der Regel Erfolg, und einer, der mit „4“ beginnt, signalisiert einen Fehler.
  • Die Header haben dieselbe Funktion wie ihre Entsprechungen. Wenn du beispielsweise eine bestimmte Art von Datei erhältst, gibt dir ein Header Auskunft über das Format.
  • Der Body ist ebenfalls vorhanden. Wenn Sie Inhalte mit GET angefordert haben und dies erfolgreich war, finden Sie die Daten hier.

REST-APIs verwenden HTTP-Protokolle, ähnlich wie Webbrowser. Wenn du also der Meinung bist, dass C++-Webscraper zu aufwendig sind, sind diese Informationen auch hilfreich, wenn du dich für die Verwendung von WebScrapingAPI entscheidest, das bereits alle Herausforderungen der Datenextraktion bewältigt.

C++ verstehen

Was Programmiersprachen angeht, gibt es kaum etwas Old-School-mäßigeres als C und C++. Die Sprache erschien 1985 als die perfektionierte Version von „C mit Klassen“.

Zwar wird C++ für die allgemeine Programmierung verwendet, doch ist es nicht unbedingt die erste Sprache, die einem für einen Web-Scraper in den Sinn käme. Es hat einige Nachteile, aber das Konzept ist nicht ohne Vorzüge. Schauen wir uns diese doch einmal an, sollen wir?

C++ ist objektorientiert, was bedeutet, dass es Klassen, Datenabstraktion und Vererbung nutzt, um Ihren Code leichter wiederverwendbar und für unterschiedliche Anforderungen anpassbar zu machen. Da Daten als Objekte behandelt werden, ist es für Sie einfacher, sie zu speichern und zu analysieren.

Viele Entwickler kennen sich zumindest ein wenig mit C++ aus. Selbst wenn Sie es nicht an der Uni gelernt haben, kennen Sie (oder ein Teamkollege) wahrscheinlich ein wenig C++. Das gilt für die gesamte Softwareentwickler-Community, sodass es Ihnen nicht schwerfallen wird, eine zweite Meinung zum Code einzuholen.

C++ ist hochgradig skalierbar. Wenn Sie mit einem kleinen Projekt beginnen und feststellen, dass Web-Scraping das Richtige für Sie ist, ist der Großteil des Codes wiederverwendbar. Ein paar kleine Anpassungen hier und da, und Sie sind bereit für viel größere Datenmengen.

Andererseits ist C++ eine statische Programmiersprache. Das sorgt zwar für eine bessere Datenintegrität, ist aber im Umgang mit dem Internet nicht so hilfreich wie dynamische Sprachen.

Außerdem eignet sich C++ nicht besonders gut für die Entwicklung von Crawlern. Das ist vielleicht kein Problem, wenn du nur einen Scraper willst. Wenn du aber einen Crawler hinzufügen willst, um URL-Listen zu generieren, ist C++ keine gute Wahl.

Ok, wir haben viele wichtige Dinge besprochen, aber kommen wir nun zum Kern des Artikels – dem Programmieren eines Web-Scrapers in C++.

Erstellen eines Web-Scrapers mit C++

Voraussetzungen

  • C++-IDE. In dieser Anleitung verwenden wir Visual Studio.
  • vcpkg ist ein C/C++-Paketmanager, der von Windows entwickelt und gepflegt wird
  • cpr ist eine C/C++-Bibliothek für HTTP-Anfragen, die als Wrapper für das klassische cURL entwickelt wurde und von der Python-Bibliothek „requests“ inspiriert ist.
  • gumbo ist ein vollständig in C geschriebener HTML-Parser, der Wrapper für mehrere Programmiersprachen bereitstellt, darunter C++.

Einrichten der Umgebung

1. Erstellen Sie nach dem Herunterladen und der Installation von Visual Studio ein einfaches Projekt mithilfe einer Konsolen-App-Vorlage.

2. Nun konfigurieren wir unseren Paketmanager. Vcpkg bietet ein gut geschriebenes Tutorial, damit Sie so schnell wie möglich loslegen können.

Hinweis: Nach Abschluss der Installation ist es hilfreich, eine Umgebungsvariable zu setzen, damit du vcpkg von jedem Ort auf deinem Computer aus ausführen kannst.

3. Nun ist es an der Zeit, die benötigten Bibliotheken zu installieren. Wenn Sie eine Umgebungsvariable gesetzt haben, öffnen Sie ein beliebiges Terminal und führen Sie die folgenden Befehle aus:

> vcpkg install cpr
> vcpkg install gumbo
> vcpkg integrate install

Wenn Sie keine Umgebungsvariable gesetzt haben, navigieren Sie einfach zu dem Ordner, in dem Sie vcpkg installiert haben, öffnen Sie ein Terminalfenster und führen Sie dieselben Befehle aus.

Die ersten beiden Befehle installieren die Pakete, die wir zum Erstellen unseres Scrapers benötigen, und der dritte hilft uns, die Bibliotheken mühelos in unser Projekt zu integrieren.

Wählen Sie eine Website aus und untersuchen Sie den HTML-Code

Und jetzt sind wir startklar! Bevor wir den Web-Scraper erstellen, müssen wir eine Website auswählen und deren HTML-Code untersuchen.

Wir haben Wikipedia aufgerufen und eine zufällige Seite aus dem Abschnitt „Wusstest du schon …“ ausgewählt. Die heute gescrapte Seite ist also der Wikipedia-Artikel über die Mohnsamen-Verteidigung, und wir werden einige seiner Komponenten extrahieren. Aber schauen wir uns zunächst die Seitenstruktur an. Klicke mit der rechten Maustaste auf eine beliebige Stelle im Artikel, dann auf „Element untersuchen“ und voilà! Der HTML-Code gehört uns.

Den Titel extrahieren

Jetzt können wir mit dem Schreiben des Codes beginnen. Um die Informationen zu extrahieren, müssen wir den HTML-Code lokal herunterladen. Importieren Sie zunächst die Bibliotheken, die wir gerade heruntergeladen haben:

#include <iostream>
#include <fstream>
#include "cpr/cpr.h"
#include "gumbo.h"

Dann senden wir eine HTTP-Anfrage an die Zielwebsite, um den HTML-Code abzurufen.

std::string extract_html_page()
{
    cpr::Url url = cpr::Url{"https://en.wikipedia.org/wiki/Poppy_seed_defence"};
    cpr::Response response = cpr::Get(url);
    return response.text;
}

int main()
{
    std::string page_content = extract_html_page();
}

Die Variable `page_content` enthält nun den HTML-Code des Artikels, und wir werden ihn weiterverwenden, um die benötigten Daten zu extrahieren. Hier kommt die Gumbo-Bibliothek ins Spiel.

Wir verwenden die Methode „gumbo_parse“, um die vorherige Zeichenkette „page_content“ in einen HTML-Baum umzuwandeln, und rufen dann unsere implementierte Funktion „search_for_title“ für den Stammknoten auf.

int main()

{

    std::string page_content = extract_html_page();

    GumboOutput* parsed_response = gumbo_parse(page_content.c_str());

    search_for_title(parsed_response->root);

    // free the allocated memory

    gumbo_destroy_output(&kGumboDefaultOptions, parsed_response);

}

Die aufgerufene Funktion durchläuft den HTML-Baum in der Tiefe, um durch rekursive Aufrufe nach dem Tag <h1> zu suchen. Wenn sie den Titel findet, zeigt sie ihn in der Konsole an und beendet die Ausführung.

void search_for_title(GumboNode* node)
{
    if (node->type != GUMBO_NODE_ELEMENT)
        return;

    if (node->v.element.tag == GUMBO_TAG_H1)
    {
        GumboNode* title_text = static_cast<GumboNode*>(node->v.element.children.data[0]);
        std::cout << title_text->v.text.text << "\n";
        return;
    }

    GumboVector* children = &node->v.element.children;
    for (unsigned int i = 0; i < children->length; i++)
        search_for_title(static_cast<GumboNode*>(children->data[i]));
}

Das gleiche Grundprinzip gilt für die übrigen Tags: Wir durchlaufen den Baum und extrahieren die gewünschten Elemente. Holen wir uns alle Links und extrahieren ihr href-Attribut.

void search_for_links(GumboNode* node)
{
    if (node->type != GUMBO_NODE_ELEMENT)
        return;

    if (node->v.element.tag == GUMBO_TAG_A)
    {
        GumboAttribute* href = gumbo_get_attribute(&node->v.element.attributes, "href");
        if (href)
            std::cout << href->value << "\n";
    }

    GumboVector* children = &node->v.element.children;
    for (unsigned int i = 0; i < children->length; i++)
    {
        search_for_links(static_cast<GumboNode*>(children->data[i]));
    }
}

Sehen Sie? Es ist fast derselbe Code, abgesehen von dem Tag, nach dem wir suchen. Die Methode `gumbo_get_attribute` kann jedes beliebige Attribut extrahieren, das wir angeben. Daher können Sie sie verwenden, um nach Klassen, IDs usw. zu suchen.

Es ist unerlässlich, den Wert des Attributs vor der Anzeige auf Null zu prüfen. In höheren Programmiersprachen ist dies nicht notwendig, da dort einfach eine leere Zeichenkette angezeigt wird, aber in C++ stürzt das Programm ab.

In CSV-Datei schreiben

Es gibt viele Links da draußen, die alle über den gesamten Inhalt verteilt sind. Und das war auch noch ein wirklich kurzer Artikel. Speichern wir sie also alle extern und schauen wir uns an, wie wir sie voneinander unterscheiden können.

Zunächst erstellen und öffnen wir eine CSV-Datei. Dies tun wir außerhalb der Funktion, direkt neben den Importen. Unsere Funktion ist rekursiv, was bedeutet, dass wir SEHR VIELE Dateien haben werden, wenn bei jedem Aufruf eine neue Datei erstellt wird.

std::ofstream writeCsv("links.csv");

Dann schreiben wir in unserer Hauptfunktion die erste Zeile der CSV-Datei, unmittelbar bevor wir die Funktion zum ersten Mal aufrufen. Vergessen Sie nicht, die Datei nach Abschluss der Ausführung zu schließen.

writeCsv << "type,link" << "\n";
search_for_links(parsed_response->root);
writeCsv.close();

Nun schreiben wir den Inhalt. In unserer Funktion `search_for_links` machen wir Folgendes, wenn wir ein `<a>`-Tag finden, anstatt es in der Konsole anzuzeigen:

if (node->v.element.tag == GUMBO_TAG_A)
{
    GumboAttribute* href = gumbo_get_attribute(&node->v.element.attributes, "href");
    if (href)
    {
        std::string link = href->value;
        if (link.rfind("/wiki") == 0)
            writeCsv << "article," << link << "\n";
        else if (link.rfind("#cite") == 0)
            writeCsv << "cite," << link << "\n";
        else
            writeCsv << "other," << link << "\n";
    }
}

Wir nehmen den Wert des href-Attributs mit diesem Code und ordnen ihn drei Kategorien zu: Artikel, Zitate und der Rest.

Natürlich kannst du noch viel weiter gehen und deine eigenen Link-Typen definieren, wie zum Beispiel solche, die wie ein Artikel aussehen, aber eigentlich eine Datei sind.

Alternativen zum Web-Scraping

Jetzt wissen Sie, wie Sie Ihren eigenen Web-Scraper mit C++ erstellen. Toll, oder?

Dennoch hast du dir vielleicht irgendwann gesagt: „Das macht langsam mehr Ärger, als es wert ist!“, und wir verstehen das vollkommen. Um ehrlich zu sein: Das Programmieren eines Scrapers ist eine hervorragende Lernerfahrung, und die Programme eignen sich für kleine Datensätze, aber das war’s dann auch schon.

Eine Web-Scraping-API ist die beste Wahl, wenn du ein schnelles, zuverlässiges und skalierbares Tool zur Datenextraktion benötigst. Denn sie bietet alle Funktionen, die du brauchst, wie einen rotierenden Proxy-Pool, Javascript-Rendering, Captcha-Löser, Geolokalisierungsoptionen und vieles mehr.

Sie glauben mir nicht? Dann überzeugen Sie sich selbst! Starten Sie Ihre kostenlose WebScrapingAPI-Testversion und finden Sie heraus, wie einfach Web Scraping sein kann!

Über den Autor
Raluca Penciuc, Full-Stack-Entwickler @ WebScrapingAPI
Raluca PenciucFull-Stack-Entwickler

Raluca Penciuc ist Full-Stack-Entwicklerin bei WebScrapingAPI. Sie entwickelt Scraper, verbessert Umgehungsstrategien und findet zuverlässige Wege, um die Erkennung auf Zielwebsites zu verringern.

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.