G2 ist der Ort, an den Software-Käufer gehen, um zu lesen, was echte Nutzer denken, bevor sie sich entscheiden. Seine Rezensionsseiten tragen die Art von Signal, die Produkt-, Vertriebs- und Competitive-Intelligence-Teams in großem Maßstab wollen: Sternebewertungen, Rezensionstiteln, den eigentlichen Prosatext jeder Rezension, die Rolle des Rezensenten oder sein Unternehmens-Segment und wann die Rezension veröffentlicht wurde. Das Problem ist, dass G2 diese Seiten dynamisch rendert und hinter aggressivem, Cloudflare-ähnlichem Bot-Schutz sitzt, sodass eine einfache HTTP-Anfrage von Node herausgefordert wird, lange bevor sie jemals eine Rezension sieht.

Diese Anleitung zeigt, wie man G2-Rezensionen mit JavaScript zuverlässig scraped. Sie erstellen ein kleines Node.js-Skript, das eine gerenderte Rezensionsseite über die Crawling API abruft, sie mit cheerio parst und je Rezension einen sauberen Datensatz extrahiert. Wir halten die gesamte Anleitung auf öffentliche Rezensionsdaten beschränkt, und der Legalitätsabschnitt gegen Ende ist kein Standardtext, also lesen Sie ihn, bevor Sie das auf beliebiges Volumen anwenden.

Was Sie bauen werden

Ein Node.js-Skript, das eine öffentliche G2-Produkt-Rezensions-URL entgegennimmt, das gerenderte HTML über die Crawling API abruft und eine strukturierte Liste von Rezensionen extrahiert. Als durchgehendes Beispiel verwenden wir die Rezensionsseite eines öffentlichen Produkts und lesen folgende Felder je Rezension aus:

  • Review title die kurze Überschrift, die ein Rezensent seiner Rezension gibt.
  • Star rating der numerische Score, zum Beispiel "4.5".
  • Review text der Body der Rezension.
  • Reviewer role or segment die öffentliche Berufsbezeichnung oder das Unternehmens-Größen-Label auf der Rezension.
  • Date wann die Rezension veröffentlicht wurde.

Dazu lesen wir auch etwas seitenbezogenen Kontext aus: den Produktnamen und den durchschnittlichen Sterne-Wert der Überschrift. Das gibt jedem Rezensions-Batch einen Anker.

Warum ein einfacher Abruf auf G2 scheitert

Wenn Sie eine G2-Rezensions-URL mit einem einfachen HTTP-Client wie fetch oder axios anfragen, erhalten Sie keine Rezensionsdaten zurück. Zwei Dinge wirken gegen Sie. Erstens rendert G2 einen Großteil seiner Rezensionsinhalte im Browser, sodass das erhaltene rohe HTML unvollständig ist, bis die Seitenskripte ausgeführt werden. Zweitens, und wichtiger, betreibt G2 aggressiven Anti-Bot-Schutz: Datacenter-IPs, fehlende Browser-Fingerprints und scrapertypische Anfragemuster erhalten eine Herausforderungsseite oder eine direkte Blockade statt des Inhalts. Sie sehen einen 403, eine CAPTCHA-Zwischenseite oder eine "Ihren Browser wird überprüft"-Warteseite statt Rezensionen.

Ein funktionsfähiger G2-Scraper braucht also zwei Dinge in einer Anfrage: eine IP, die die Plattform als echten Besucher liest, und Rendering, wenn die Seite es benötigt. Sie können versuchen, das selbst mit einem Headless-Browser und einem Pool aus rotierenden Residential-Proxys zusammenzustellen, aber diesen Stack gegen ein Ziel, das aktiv gegen Bots kämpft, gesund zu halten, ist der größte Teil der Arbeit. Die Crawling API bündelt beides in einem einzigen Aufruf: Sie übergeben ihr die URL, sie ruft die Seite hinter einer vertrauenswürdigen Residential-IP mit der richtigen Behandlung für das Ziel ab und gibt nutzbares HTML zum Parsen zurück.

G2 is a hard target

G2s Bot-Abwehr ist stärker als auf einer typischen Website, also verwendet die Crawling API einen speziellen Pfad dafür statt eines generischen Abrufs. Wenn Sie sich registrieren und Ihre G2-Anfragen immer noch als Herausforderungen zurückkommen, wenden Sie sich an den Support, um die G2-spezifische Behandlung für Ihr Konto zu aktivieren. Sobald sie aktiviert ist, funktioniert der folgende Code unverändert.

Voraussetzungen

Vor dem Schreiben von Code müssen einige Dinge vorhanden sein. Keines davon nimmt viel Zeit in Anspruch.

Grundlegendes JavaScript und Node. Sie sollten in der Lage sein, ein Node.js-Skript zu schreiben und auszuführen sowie Pakete mit npm zu installieren. Wer neu im Aufbau von Scrapern mit diesem Stack ist, findet in unserem Walkthrough zum Aufbau eines Web-Scrapers mit Node.js einen sanften Einstieg.

Node.js installiert. Bestätigen Sie mit node --version. Falls nicht installiert, laden Sie das LTS-Build von nodejs.org herunter und führen Sie das Installationsprogramm für Ihr Betriebssystem aus.

Ein Crawlbase-Konto und Token. Registrieren Sie sich, öffnen Sie Ihr Dashboard und kopieren Sie Ihren Request-Token von der Konto-Dokumentationsseite. Behandeln Sie den Token wie ein Passwort: Er authentifiziert Ihre Anfragen, also bewahren Sie ihn aus der Versionskontrolle und aus jeder committeten Datei heraus.

Projekt einrichten

Erstellen Sie einen frischen Projektordner, initialisieren Sie ihn und installieren Sie die zwei Bibliotheken, die der Scraper benötigt: den offiziellen Crawlbase-Client und cheerio zum Parsen.

bash
mkdir g2-reviews-scraper
cd g2-reviews-scraper
npm init --yes

npm install crawlbase cheerio

Zwei Abhängigkeiten erledigen die Arbeit: crawlbase ist der offizielle Client für die Crawling API, und cheerio bietet eine jQuery-ähnliche API zum Abfragen des zurückgegebenen HTML, sodass Sie einzelne Felder per CSS-Selektor auslesen können. Sie brauchen weder Express, eine Datenbank noch einen Web-Server, um die Daten zu extrahieren; diese gehören in was auch immer Sie rund um den Scraper bauen, nicht in den Scraper selbst.

Schritt 1: Die gerenderte Rezensionsseite abrufen

Beginnen Sie damit, die Seite überhaupt zurückzuerhalten. Importieren Sie die CrawlingAPI-Klasse, initialisieren Sie sie mit Ihrem Token und fordern Sie die Rezensions-URL des Produkts an. Die Statusprüfung vor dem Parsen lässt Fehler laut statt still auftreten, was bei einem Ziel sehr wichtig ist, das Herausforderungsseiten mit einem 200-Body zurückgibt, wenn Sie nicht aufpassen.

javascript
const { CrawlingAPI } = require("crawlbase");

const api = new CrawlingAPI({ token: "YOUR_CRAWLBASE_TOKEN" });

async function crawl(pageUrl) {
  const response = await api.get(pageUrl);
  if (response.statusCode === 200) {
    return response.body;
  }
  console.error(`Request failed: ${response.statusCode}`);
  return null;
}

(async () => {
  const pageUrl = "https://www.g2.com/products/xcode/reviews";
  const html = await crawl(pageUrl);
  console.log(html ? html.slice(0, 500) : "No HTML returned");
})();

Speichern Sie dies als scraper.js und führen Sie es mit node scraper.js aus. Wenn alles korrekt verbunden ist, sehen Sie echtes Rezensions-Markup in den ersten 500 Zeichen, keine Herausforderungsseite. Diese einzelne Prüfung bestätigt, dass der schwierige Teil, G2s Abwehr zu überwinden, funktioniert, bevor Sie einen einzigen Selektor schreiben. Falls G2 jemals eine Seite liefert, die clientseitiges Rendering zum Befüllen benötigt, fügen Sie einen JavaScript-Token und die Optionen ajax_wait und page_wait zur Anfrage hinzu; für die Standard-Rezensionsseite reicht der Standard-Abruf über die API in der Regel aus.

Crawlbase Crawling API

G2 bekämpft Bots hart, also liegt der Wert nicht im Parsen von HTML, sondern darin, überhaupt sauberes HTML zurückzubekommen. Die Crawling API ruft die Seite hinter rotierenden Residential-IPs mit G2-spezifischer Behandlung ab, absorbiert die Herausforderungen und CAPTCHAs und liefert das Markup, damit Sie selbst keine Headless-Flotte und keinen Proxy-Pool betreiben müssen. Testen Sie es auf einer öffentlichen Rezensionsseite im kostenlosen Kontingent.

Schritt 2: Rezensionen mit cheerio parsen

Mit nutzbarem HTML laden Sie es in cheerio und gehen die Rezensionsliste durch. G2 legt jede Rezension als wiederkehrende Karte aus, also lautet das Muster: seitenbezogenen Kontext einmal auswählen, dann die Rezensionselemente iterieren und dieselben Felder aus jedem einzeln auslesen. Umschließen Sie die Extraktion in einem try/catch, damit eine fehlerhafte Karte den gesamten Lauf nicht abbricht.

javascript
const cheerio = require("cheerio");

function parseReviews(html) {
  try {
    const $ = cheerio.load(html);
    const data = {
      productName: $(".product-head [itemprop=name]").text().trim(),
      averageStars: $("#products-dropdown .fw-semibold").first().text().trim(),
      reviews: [],
    };

    $(".nested-ajax-loading > div.paper").each((_, el) => {
      const card = $(el);
      const title = card.find("[itemprop=name]").first().text().trim();
      const stars = card.find("[itemprop='ratingValue']").attr("content");
      const text = card.find(".pjax").text().trim();
      const role = card.find("[ue=tooltip]")
        .map((_, label) => $(label).text().trim())
        .get()
        .join(", ");
      const date = card.find(".x-current-review-date").text().trim();

      data.reviews.push({ title, stars, text, role, date });
    });

    return data;
  } catch (error) {
    console.error("Parse error:", error.message);
    return null;
  }
}

Einige Dinge sind es wert, hervorzuheben. Die Sternebewertung wird aus dem content-Attribut des ratingValue-Elements gelesen statt aus dem sichtbaren Text, da G2 den numerischen Score dort sauber bereitstellt. Die Rolle oder das Segment des Rezensenten wird aus den Tooltip-Labels extrahiert, die G2 an jede Karte anfügt, zu einer einzigen Zeichenkette verbunden, da eine Rezension mehr als ein öffentliches Label tragen kann, zum Beispiel eine Berufsbezeichnung plus ein Unternehmens-Größen-Band. Alles wird getrimmt, damit Sie keine mit Leerzeichen aufgefüllten Rezensionen speichern.

Selectors drift

G2s Klassennamen und Markup ändern sich ohne Vorankündigung. Betrachten Sie die obigen Selektoren als Ausgangspunkt, nicht als Vertrag. Wenn ein Feld bei jeder Rezension leer zurückkommt, inspizieren Sie die Live-Seite in den Entwicklertools Ihres Browsers und aktualisieren Sie den Selektor. Regelmäßige Selektor-Wartung ist bei jedem Produktions-Scraper normal, kein Zeichen, dass etwas kaputt ist.

Schritt 3: Alles zusammenfügen

Verbinden Sie jetzt Abruf und Parse zu einem lauffähigen Skript. Rufen Sie das gerenderte HTML ab, übergeben Sie es an den Parser und geben Sie das strukturierte Ergebnis aus. Das ist der gesamte Scraper in einer Datei.

javascript
const { CrawlingAPI } = require("crawlbase");
const cheerio = require("cheerio");

const api = new CrawlingAPI({ token: "YOUR_CRAWLBASE_TOKEN" });

async function crawl(pageUrl) {
  const response = await api.get(pageUrl);
  if (response.statusCode === 200) {
    return response.body;
  }
  console.error(`Request failed: ${response.statusCode}`);
  return null;
}

function parseReviews(html) {
  const $ = cheerio.load(html);
  const data = {
    productName: $(".product-head [itemprop=name]").text().trim(),
    averageStars: $("#products-dropdown .fw-semibold").first().text().trim(),
    reviews: [],
  };

  $(".nested-ajax-loading > div.paper").each((_, el) => {
    const card = $(el);
    data.reviews.push({
      title: card.find("[itemprop=name]").first().text().trim(),
      stars: card.find("[itemprop='ratingValue']").attr("content"),
      text: card.find(".pjax").text().trim(),
      role: card.find("[ue=tooltip]")
        .map((_, label) => $(label).text().trim()).get().join(", "),
      date: card.find(".x-current-review-date").text().trim(),
    });
  });

  return data;
}

(async () => {
  const pageUrl = "https://www.g2.com/products/xcode/reviews";
  const html = await crawl(pageUrl);
  if (!html) return;
  const data = parseReviews(html);
  console.log(JSON.stringify(data, null, 2));
})();

Wie die Ausgabe aussieht

Führen Sie das vollständige Skript mit node scraper.js aus und Sie erhalten ein sauberes strukturiertes Objekt: das Produkt, seine Durchschnittsbewertung und ein Array von Rezensionen, jede bereit zum Schreiben in JSON, CSV oder eine Datenbank.

json
{
  "productName": "Xcode",
  "averageStars": "4.5",
  "reviews": [
    {
      "title": "Solid IDE for native Apple development",
      "stars": "5",
      "text": "The integration with the Apple toolchain is seamless...",
      "role": "Software Engineer, Small-Business",
      "date": "Aug 12, 2025"
    }
  ]
}

Skalierung über Rezensionsseiten hinweg

Eine Seite ist eine Demo; ein echter Auftrag läuft über jede Rezensionsseite eines Produkts, oft über mehrere Produkte hinweg. G2 paginiert seine Rezensionen, sodass die gewünschte Seite durch Anhängen einer Seitennummer an die Rezensions-URL erreichbar ist. Die Form bleibt dieselbe: Erstellen Sie die Seiten-URL, rufen Sie sie über die Crawling API ab, parsen Sie sie mit derselben Funktion und sammeln Sie die Zeilen, bis eine Seite leer zurückkommt.

javascript
function sleep(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

async function scrapeAllPages(productSlug, maxPages) {
  const base = `https://www.g2.com/products/${productSlug}/reviews`;
  const all = [];

  for (let page = 1; page <= maxPages; page++) {
    const url = page === 1 ? base : `${base}?page=${page}`;
    const html = await crawl(url);
    if (!html) break;

    const { reviews } = parseReviews(html);
    if (!reviews.length) break;

    all.push(...reviews);
    await sleep(2000);
  }

  return all;
}

Zwei Details halten das gesund. Die Schleife stoppt, sobald eine Seite keine Rezensionen zurückgibt, sodass Sie nicht über das Ende der Liste hinaus anfordern. Und der sleep-Aufruf zwischen Anfragen dosiert den Lauf; G2 in einem engen Loop zu hämmern, ist der schnellste Weg zur Drosselung, selbst mit einer verwalteten API davor. Zwei Sekunden sind eine vernünftige Untergrenze. Wenn Sie viele Produkte abrufen, ermöglicht der asynchrone Crawler, URLs zu übergeben und Ergebnisse über Webhook zu sammeln, statt auf jeden Abruf blockierend zu warten.

Geblockt bleiben verhindern

Auch wenn die Crawling API den Großteil von G2s Abwehr absorbiert, halten einige Gewohnheiten einen langen Lauf gesund, und sie gelten für jedes schwierige kommerzielle Ziel.

  • Dosieren Sie Ihre Anfragen. Verteilen Sie Anfragen mit einer Verzögerung zwischen Seiten, statt sie so schnell wie die Schleife erlaubt abzufeuern. Stetig und langsam beendet; schnell und gierig wird herausgefordert.
  • Setzen Sie auf Rotation. Ein Pool aus Residential-IPs verteilt Anfragen über viele echte Nutzer-Adressen, sodass keine einzelne ein Rate-Limit auslöst. Die Crawling API erledigt das für Sie; wenn Sie jemals Ihren eigenen Stack aufbauen, ist das der Teil, den Sie richtig machen müssen.
  • Lesen Sie die Statuscodes. Ein Lauf, der beginnt, 403-Fehler oder Herausforderungsseiten zurückzugeben, zeigt Ihnen, dass die aktuelle Rate zu hoch ist. Treten Sie einen Schritt zurück und verlangsamen Sie, statt es aggressiver zu versuchen.

Das umfassende Playbook finden Sie unter Wie man Cloudflare umgeht und Bot-Erkennung vermeidet und in der tieferen Einführung Wie man CAPTCHAs beim Web-Scraping umgeht. Wenn Sie Ihren eigenen Node-Traffic lieber durch einen rotierenden Pool leiten statt die verwaltete API zu nutzen, bietet der Smart AI Proxy dieselbe Residential-IP-Rotation als Drop-in-Proxy-Endpunkt. Und wenn Rezensionen auf anderen Seiten als nächstes auf Ihrer Liste stehen, deckt unser Leitfaden zum Scrapen von Kundenrezensionen das allgemeine Muster ab.

Ob das Scrapen von G2 erlaubt ist, hängt von G2s Nutzungsbedingungen, Ihrer Jurisdiktion und dem Verwendungszweck der Daten ab. G2s Bedingungen schränken den automatisierten Zugriff ein, sodass Scraping unabhängig von der Sorgfalt Ihrer Werkzeuge gegen diese Bedingungen verstoßen kann. Keiner der hier gezeigten Code ändert das; er lässt lediglich den technischen Teil funktionieren. Lesen Sie G2s Nutzungsbedingungen und die robots.txt und behandeln Sie beides als Grenze dessen, was Sie sammeln.

Einige Linien, an denen man festhalten sollte. Sammeln Sie nur öffentlich angezeigte Rezensionsdaten: Rezensionsttitel, Sternebewertung, Rezensionstext, das öffentliche Rollen- oder Segment-Label und das Datum, das jeder auf einer öffentlichen Rezensionsseite ohne Anmeldung sehen kann. Respektieren Sie G2s angegebene Erwartungen und halten Sie Ihr Anfragevolumen niedrig genug, damit Sie seine Server nicht belasten. Sammeln Sie keine persönlichen oder Kontaktdaten von Rezensenten jenseits dessen, was öffentlich angezeigt wird, und versuchen Sie nicht, eine öffentliche Rezension mit einer privaten Identität anzureichern.

Diese Anleitung ist bewusst auf öffentliche, login-freie Rezensionsseiten beschränkt, weil das die Grenze ist, die die Arbeit vertretbar macht. Sie deckt nichts hinter einem Login ab, keine durch ein G2-Konto oder eine bezahlte Stufe gesperrten Daten, keine persönlichen oder Kontaktdaten von Rezensenten jenseits dessen, was öffentlich ist, und keine Versuche, die Authentifizierung oder G2s Schutz zu umgehen, um auf gesperrte Inhalte zuzugreifen. G2 betreibt aus gutem Grund starke Bot-Abwehr; die richtige Haltung ist, nur zu lesen, was es der Öffentlichkeit zeigt, in einem vernünftigen Tempo. Wenn Ihr Projekt mehr als öffentliche Rezensionsdaten erfordert, ist eine offizielle Datenvereinbarung der richtige Weg, kein ausgefeilterer Scraper.

Zusammenfassung

Wichtigste Erkenntnisse

  • G2 blockiert einfache Abrufe. Seine Cloudflare-ähnliche Abwehr liefert Herausforderungen und 403-Fehler an einfache HTTP-Clients, also ist sauberes HTML zurückzubekommen der schwierige Teil, nicht das Parsen.
  • Die Crawling API übernimmt die schwere Arbeit. Sie ruft die Seite hinter rotierenden Residential-IPs mit G2-spezifischer Behandlung in einem Aufruf ab, damit Sie selbst keine Headless-Flotte und keinen Proxy-Pool betreiben müssen.
  • cheerio übernimmt die Extraktion. Iterieren Sie die Rezensionskarten und ordnen Sie Titel, Sterne, Text, öffentliche Rolle oder Segment und Datum den aktuellen Selektoren zu, und erwarten Sie, dass diese Selektoren abweichen.
  • Skalierung durch Seitenloop. Hängen Sie eine Seitennummer an, rufen Sie ab, parsen Sie und dosieren Sie jede Anfrage mit einer Verzögerung, damit ein langer Lauf keine Drosselung auslöst.
  • Bleiben Sie bei öffentlichen Daten. Respektieren Sie G2s Nutzungsbedingungen und robots.txt, sammeln Sie nur öffentlich angezeigte Rezensionsfelder und berühren Sie niemals Logins, gesperrte Daten oder persönliche Daten von Rezensenten.

Häufig gestellte Fragen

Warum gibt ein einfacher Abruf keine Rezensionen von G2 zurück?

Weil G2 aggressiven Anti-Bot-Schutz betreibt und einen Teil seines Rezensionsinhalts clientseitig rendert. Eine rohe HTTP-Anfrage von Node trifft auf eine Herausforderungsseite, ein CAPTCHA oder einen 403 lange vor dem Rezensions-Markup. Um echte Daten zu erhalten, müssen Sie die Seite hinter einer IP abrufen, die G2 als echten Besucher liest, mit Rendering wenn die Seite es benötigt, was die Crawling API für Sie erledigt.

Brauche ich für G2 ein spezielles Setup?

Ja. G2s Abwehr ist stärker als bei einer typischen Website, also verwendet die Crawling API einen speziellen Pfad dafür. Wenn Sie sich registrieren und Ihre G2-Anfragen immer noch als Herausforderungen zurückkommen, wenden Sie sich an den Support, um die G2-spezifische Behandlung für Ihr Konto zu aktivieren. Sobald sie aktiviert ist, funktioniert der Code in dieser Anleitung ohne Änderungen.

Wie verwalte ich die Paginierung über G2-Rezensionsseiten hinweg?

G2 paginiert Rezensionen, also ist die nächste Seite durch Anhängen einer Seitennummer an die Rezensions-URL erreichbar, zum Beispiel ?page=2. Iterieren Sie von Seite eins aufwärts, rufen Sie jede Seite mit derselben Funktion ab und parsen Sie sie, und stoppen Sie, sobald eine Seite keine Rezensionen zurückgibt. Setzen Sie eine Verzögerung zwischen Anfragen, damit der Lauf nicht gedrosselt wird.

Meine Selektoren geben leere Zeichenketten zurück. Was hat sich geändert?

Mit ziemlicher Sicherheit G2s Markup. Seine Klassennamen und Kartenstruktur ändern sich ohne Vorankündigung, sodass Selektoren, die letzten Monat funktionierten, jetzt brechen können. Inspizieren Sie eine Live-Rezensionsseite in den Entwicklertools Ihres Browsers und aktualisieren Sie die Selektoren. Regelmäßige Selektor-Wartung ist bei jedem Produktions-Scraper normal, kein Zeichen, dass der Ansatz falsch ist.

Kann ich Rezensenten-Namen, E-Mails oder andere personenbezogene Daten von G2 scrapen?

Nein, und diese Anleitung deckt das nicht ab. Beschränken Sie Ihre Sammlung auf öffentlich angezeigte Rezensionsfelder: Titel, Sternebewertung, Rezensionstext, das öffentliche Rollen- oder Segment-Label und das Datum. Persönliche oder Kontaktdaten von Rezensenten jenseits dessen, was öffentlich angezeigt wird, alles hinter einem Login und Versuche, die Authentifizierung zu umgehen, liegen alle außerhalb des Geltungsbereichs dieser Anleitung und verstoßen gegen G2s Bedingungen. Für mehr als öffentliche Rezensionsdaten ist eine offizielle Datenvereinbarung der richtige Weg.

In welcher Datenbank soll ich die Rezensionen speichern?

In was auch immer zu Ihrem Stack passt. Der Scraper gibt einfache JSON-Objekte zurück, sodass sie sauber in PostgreSQL, MySQL, MongoDB, einen Cloud-Speicher oder sogar eine flache JSON- oder CSV-Datei für einen kleinen Lauf fallen. Die Extraktion ist bewusst vom Speicher entkoppelt, sodass Sie später wählen können, ohne den Parser zu berühren.

Jetzt loslegen

Crawlen Sie jede Website im großen Maßstab, ohne gegen die Infrastruktur zu kämpfen.

Crawlbase übernimmt Proxys, Fingerprints und CAPTCHAs, damit Ihr Team Datenpipelines ausliefert, statt Crawl-Infrastruktur zu pflegen. 1.000 Anfragen kostenlos, keine Karte erforderlich.

Self-Service · Kein Verkaufsgespräch erforderlich · Enterprise-Crawl-Volumen verfügbar