ProgrammierungTechnologie

PrestaShop-Webservice-API für automatisierte SEO-Landingpages

netcomputing.de Redaktion26. August 202611 Min. Lesezeit

Zusammenfassung

Landingpages pro Kategorie-Attribut-Kombination von Hand zu schreiben kostet bei hundert Kombinationen Wochen. Die PrestaShop-Webservice-API liefert Produktdaten per REST-Aufruf, ein Generator-Skript baut daraus Seiten, ein Sprachmodell formuliert je Seite einen Absatz aus den Daten. Ohne Mindesttext und Canonical-Disziplin stuft Google das als automatisiert erzeugten Masseninhalt ein. So entstehen aus einem Katalog hunderte indexierbare Seiten in einem Build-Lauf statt in Wochen Redaktion.

Ein Redakteur, der für jede Kombination aus Produktkategorie und Attribut eine eigene Landingpage schreibt, braucht dafür üblicherweise ein bis zwei Stunden pro Seite. Bei einem Katalog mit mehreren hundert Kombinationen sind das Wochen reiner Schreibarbeit, bevor überhaupt eine Seite online geht. Das lässt sich kaum skalieren. Die PrestaShop-Webservice-API, eine im Shopsystem PrestaShop eingebaute Programmierschnittstelle für den lesenden und schreibenden Zugriff auf Shopdaten, ersetzt die Handarbeit durch ein Skript, das Produktdaten automatisiert aus dem Shop zieht und daraus Seiten baut. Der Preis dafür ist ein reales Risiko: Wer nur den Kategorienamen in eine feste Vorlage einsetzt, erzeugt hunderte fast identische Seiten, und genau das bestraft Google als automatisiert erzeugten Masseninhalt ohne eigenen Wert.

Systemvoraussetzungen

KomponenteAnforderung
PrestaShopVersion 8.2.x oder 9.1.x, Webservice-Modul ist Kernbestandteil und braucht keine Zusatzinstallation
PHP8.1 bis 8.3, von beiden genannten PrestaShop-Versionslinien unterstützt
Verbindung zum ShopHTTPS, weil der Webservice-Schlüssel sonst unverschlüsselt übertragen wird
Webservice-Schlüssel (WS_KEY)32-stelliger Schlüssel, erzeugt unter Erweiterte Parameter, Menüpunkt Webservice
Ressourcen-Rechte des SchlüsselsLesezugriff (GET) mindestens auf products, categories, product_features, product_feature_values und stock_availables
Generator-LaufzeitNode.js in einer aktuellen LTS-Version oder eine gleichwertige serverseitige Laufzeit für das Seiten-Generierungsskript
Zugang zu einem Sprachmodell (optional)API-Schlüssel eines Anbieters für die automatisierte Formulierung des Einleitungsabsatzes je Seite

Systemarchitektur

flowchart TD
  A[PrestaShop Datenbank] --> B[Webservice Modul prueft WS_KEY]
  B --> C[Generator Skript ruft GET Produkte ab]
  C --> D[Produkte nach Kategorie und Merkmal gruppieren]
  D --> E[Lagerbestand aus stock_availables ergaenzen]
  E --> F[Sprachmodell erzeugt Einleitungsabsatz aus den Feldern]
  E --> G[Vorlage fuellt Tabelle mit Preisen und Merkmalen]
  F --> H[Landingpage HTML zusammensetzen]
  G --> H
  H --> I[Mindesttext und Canonical Regel pruefen]
  I --> J[Seite indexierbar oder noindex]
  J --> K[Sitemap aktualisieren und veroeffentlichen]

Das Generator-Skript meldet sich mit dem Webservice-Schlüssel bei PrestaShop an und ruft die Produktliste über die Ressource products ab, gefiltert nach Kategorie. Aus den zurückgelieferten Datensätzen bildet das Skript Gruppen: Jede Kombination aus Kategorie und Merkmalswert wird zu einer eigenen Gruppe, und jede Gruppe wird später zu genau einer Landingpage. Für jede Gruppe holt das Skript zusätzlich den Lagerbestand aus der separaten Ressource stock_availables, weil PrestaShop den Lagerbestand nicht direkt am Produktdatensatz führt, sondern in einer eigenen Tabelle, die über die Produkt-ID verknüpft ist. Aus denselben Feldern erzeugt ein Sprachmodell den Einleitungsabsatz, während eine Vorlage parallel die Tabelle mit Preisen und Merkmalen füllt. Beide Teile fließen in eine HTML-Seite zusammen. Bevor diese Seite veröffentlicht wird, prüft das Skript, ob genug einzigartiger Text und genug Produkte in der Gruppe stehen: Reicht beides nicht aus, bekommt die Seite ein noindex-Tag, eine Anweisung im HTML-Kopf, die Suchmaschinen von der Aufnahme in den Suchindex abhält, das Crawlen aber weiterhin erlaubt. Reicht es aus, wandert die Seite in die Sitemap, ein Verzeichnis aller Seiten im XML-Format, das Suchmaschinen mitteilt, welche URLs es zu prüfen gibt.

Schritt-für-Schritt-Umsetzung

Webservice-Modul aktivieren und Schlüssel mit Leserechten anlegen

Der Zugriff beginnt in der Backoffice-Verwaltung von PrestaShop, im Menü Erweiterte Parameter unter dem Punkt Webservice. Dort steht ein Schalter Webservice aktivieren, der auf Ja gestellt werden muss. Danach legt die Schaltfläche Neuen Webservice-Schlüssel hinzufügen einen neuen Zugang an: PrestaShop erzeugt auf Wunsch automatisch einen 32-stelligen Schlüssel, den WS_KEY, der bei jedem API-Aufruf als Benutzername mitgeschickt wird. Für jede Ressource, etwa products oder stock_availables, zeigt dieselbe Seite eine Rechte-Matrix mit den Kästchen GET, POST, PUT, DELETE und HEAD. Ein Häkchen bei GET erlaubt lesenden Zugriff, ein Häkchen bei POST, PUT oder DELETE erlaubt das Anlegen, Ändern oder Löschen von Datensätzen über die API. Für eine reine Leseanwendung wie diese Pipeline genügt GET auf den benötigten Ressourcen. Jedes zusätzliche Häkchen vergrößert nur die Angriffsfläche, falls der Schlüssel einmal abhandenkommt.

Wer die Aktivierung in ein Deploy-Skript einbauen will, kann sie auch direkt aus dem PrestaShop-Code heraus setzen:

Configuration::updateValue('PS_WEBSERVICE', 1);

Produktdaten per REST-Aufruf abrufen

Die Webservice-API folgt dem REST-Schema: Jede Ressource hat eine eigene Adresse und wird über die Standard-HTTP-Befehle GET, POST, PUT und DELETE angesprochen. Die Standardausgabe ist bis heute XML, ein Format mit spitzen Klammern um jedes Feld. Für die Weiterverarbeitung in einem TypeScript-Skript ist JSON praktischer, das gängige Datenformat mit geschweiften Klammern, das sich ohne zusätzlichen Parser in ein Objekt umwandeln lässt. Der Parameter output_format=JSON schaltet die Antwort auf JSON um, ohne die Anfrage selbst zu verändern. Die Anmeldung läuft über HTTP Basic Auth, ein Verfahren, bei dem Benutzername und Passwort direkt im Anfragekopf übertragen werden: Der Webservice-Schlüssel ist der Benutzername, das Passwortfeld bleibt leer.

curl -u 'WS_KEY:' \
  'https://shop.example.com/api/products?output_format=JSON&filter[id_category_default]=12&display=[id,reference,price,name]'

Der Parameter filter[id_category_default]=12 grenzt die Antwort auf Produkte ein, deren Standardkategorie die ID 12 trägt. Der Parameter display=[id,reference,price,name] begrenzt die Antwort auf die vier genannten Felder und spart damit Datenvolumen, das sonst ungenutzt über die Leitung ginge. Dieselbe Filtersyntax erlaubt auch Vergleiche und Oder-Verknüpfungen, etwa filter[price]=>[50] für alle Produkte ab 50 Euro oder filter[reference]=[ABC123|DEF456] für eine von zwei Referenzen. In einem Generator-Skript sieht derselbe Aufruf mit der eingebauten fetch-Funktion von Node.js so aus:

const url =
  'https://shop.example.com/api/products?output_format=JSON&filter[id_category_default]=12&display=[id,reference,price,name]';

const response = await fetch(url, {
  headers: {
    Authorization:
      'Basic ' + Buffer.from(process.env.PRESTASHOP_WS_KEY + ':').toString('base64'),
  },
});

if (!response.ok) {
  throw new Error('PrestaShop-API antwortete mit Status ' + response.status);
}

const payload = await response.json();
const produkte = payload.products;

Landingpage-Kombinationen aus den Rohdaten bilden

Eine Landingpage entsteht nicht pro einzelnem Produkt, sondern pro Kombination aus Kategorie und einem Produktmerkmal, zum Beispiel Kategorie Aussenbeleuchtung zusammen mit dem Merkmal Material: Aluminium. Der Produktdatensatz trägt in seinem Associations-Block bereits die IDs seiner Merkmale und Merkmalswerte; die beiden Ressourcen product_features und product_feature_values liefern dazu die lesbaren Namen, zum Beispiel Material für das Merkmal und Aluminium für den Wert. Der Kategoriename für die spätere Überschrift und den Prompt kommt aus einem zusätzlichen Aufruf der Ressource categories mit der jeweiligen Kategorie-ID. Das Generator-Skript gruppiert die zuvor abgerufenen Produkte nach dieser Zuordnung:

type ProduktEintrag = {
  id: number;
  reference: string;
  price: string;
  name: string;
  idCategoryDefault: number;
};

function nachKategorieUndMerkmalGruppieren(
  produkte: ProduktEintrag[],
  merkmalWertJeProdukt: Map<number, string>
) {
  const gruppen = new Map<string, ProduktEintrag[]>();
  for (const produkt of produkte) {
    const merkmal = merkmalWertJeProdukt.get(produkt.id) ?? 'ohne-merkmal';
    const schluessel = produkt.idCategoryDefault + '-' + merkmal;
    const bisherige = gruppen.get(schluessel) ?? [];
    bisherige.push(produkt);
    gruppen.set(schluessel, bisherige);
  }
  return gruppen;
}

Jeder Eintrag in der Map gruppen wird zu genau einer Seite. Eine Gruppe mit nur einem oder zwei Produkten liefert kaum eigenen Inhalt und ist ein Kandidat für die Mindesttextprüfung aus dem letzten Schritt dieser Anleitung.

Einleitungsabsatz vom Sprachmodell nur aus den abgerufenen Feldern erzeugen

Ein Sprachmodell, ein KI-System, das aus einer Textanweisung einen neuen Text erzeugt, formuliert aus den Feldern jeder Gruppe einen kurzen Absatz, der die Seite von den anderen Landingpages unterscheidet. Damit das Modell keine Angaben erfindet, darf sein Prompt, die Textanweisung, die an das Modell geschickt wird, ausschließlich die tatsächlich abgerufenen Felder enthalten, und die Anweisung muss das Erfinden von Werten ausdrücklich verbieten.

System: Du bekommst ausschliesslich die folgenden Datenfelder eines Produkts.
Formuliere daraus einen Absatz von 40 bis 60 Woertern in deutscher Sprache.
Verwende keine Angabe, die nicht in den Feldern steht.
Erfinde keine Spezifikation, keinen Preis und keine Verfuegbarkeit.

Kategorie: {kategorieName}
Merkmal: {merkmalName}: {merkmalWert}
Anzahl Produkte in dieser Gruppe: {anzahl}
Preisspanne: {minPreis} bis {maxPreis} Euro
Lagerbestand insgesamt: {lagerbestand} Stueck (Quelle: stock_availables)

Die geschweiften Platzhalter werden vor dem Versand durch die echten Werte aus der Gruppe ersetzt. Ein zusätzlicher Prüfschritt nach der Antwort des Modells vergleicht jede im Text genannte Zahl mit den Ausgangsdaten und verwirft den Absatz, wenn eine Zahl nicht übereinstimmt. Ohne diesen Abgleich kann ein Sprachmodell einen Preis leicht runden oder eine Verfügbarkeit nennen, die zum Zeitpunkt der Veröffentlichung schon veraltet ist.

Mindesttext, Canonical-Tag und Noindex vor der Veröffentlichung prüfen

Google stuft in seinen Richtlinien gegen Spam automatisiert erzeugte Seiten, deren Hauptzweck die Beeinflussung der Suchrangliste ist und die Nutzern keinen eigenen Wert bieten, als Missbrauch durch massenhaft erzeugte Inhalte ein, im Original Scaled Content Abuse genannt. Entscheidend ist laut dieser Richtlinie nicht die Erzeugungsmethode, sondern der Zweck der Seite. Drei Maßnahmen setzen diese Grenze technisch um, bevor eine Landingpage online geht.

  • Mindestmenge an Produkten je Gruppe: Eine Gruppe mit weniger Produkten als ein festgelegter Schwellenwert, zum Beispiel fünf, bekommt kein eigenes Canonical-Tag auf sich selbst. Ein Canonical-Tag ist ein Verweis im HTML-Kopf einer Seite, der einer Suchmaschine sagt, welche von mehreren ähnlichen Seiten als maßgebliche Version gilt. Eine zu kleine Gruppe zeigt per Canonical-Tag auf die nächsthöhere Kategorieseite, die alle Produkte ohne Merkmalsfilter zeigt.
  • Mindestmenge an einzigartigem Text: Nur der vom Sprachmodell erzeugte Absatz und die aus echten Werten berechnete Preisspanne zählen als einzigartig. Die restliche Seite, Navigation, Tabellenkopf und Fußzeile, ist auf jeder Landingpage identisch und zählt nicht mit. Unterschreitet eine Seite eine festgelegte Wortzahl an einzigartigem Text, bekommt sie ein noindex-Tag statt eines eigenen Eintrags im Suchindex.
  • Sitemap nur mit indexierbaren Seiten: Nur Landingpages ohne noindex-Tag werden in die Sitemap aufgenommen, damit Suchmaschinen ihre begrenzte Crawling-Kapazität nicht mit Seiten verbrauchen, die ohnehin nicht in den Index sollen.

Diese drei Maßnahmen sind keine Erfindung für diese Pipeline. Sie entsprechen der Empfehlung, die Google für die sogenannte facettierte Navigation gibt, bei der Filterkombinationen in einem Online-Shop dieselbe Häufung fast identischer Seiten erzeugen kann wie ein Landingpage-Generator.

Häufige Fehlerquellen

  • 401 Unauthorized bei jedem Aufruf: Der Schlüssel ist deaktiviert, falsch eingetragen oder im Passwortfeld statt im Benutzernamen-Feld gesetzt. PrestaShop erwartet den WS_KEY als Benutzername bei HTTP Basic Auth und ein leeres Passwort. Prüfen, ob der Schlüssel in der Webservice-Übersicht als aktiviert markiert ist und ob für die angefragte Ressource wenigstens das Häkchen bei GET gesetzt ist.
  • 401 Unauthorized trotz richtigem Schlüssel: Die Rechte-Matrix erlaubt für diese Ressource nur andere HTTP-Methoden, zum Beispiel POST statt GET. Jede Ressource braucht ihr eigenes Häkchen; ein Schlüssel mit Leserecht auf products hat damit noch kein Leserecht auf stock_availables.
  • 500 Internal Server Error bei einem Filter: Der Parameter filter[] verweist auf ein Feld, das für diese Ressource nicht existiert oder nicht als filterbar markiert ist. PrestaShop wirft dafür eine interne Ausnahme, die je nach Servereinstellung als leere Seite oder als 500-Fehler beim Client ankommt. Vor dem produktiven Einsatz das Feld gegen das Schema der Ressource prüfen, abrufbar über den Parameter schema=synopsis auf derselben Ressourcen-Adresse.
  • JSON-Parser bricht mit einem Syntaxfehler ab: Die Standardausgabe der Webservice-API ist weiterhin XML, auch in aktuellen Versionen. Fehlt der Parameter output_format=JSON in der Anfrage, liefert PrestaShop ein XML-Dokument, das ein JSON-Parser als ungültig zurückweist. Schreibende Aufrufe (POST, PUT) erwarten zusätzlich weiterhin einen XML-Anfragekörper, weil die Webservice-API zwar JSON ausgeben, aber kein JSON entgegennehmen kann.

Häufig gestellte Fragen

Muss jede per PrestaShop-Webservice-API erzeugte Landingpage einen komplett eigenen Text bekommen, um bei Google indexiert zu werden?

Eine per PrestaShop-Webservice-API erzeugte Landingpage braucht keinen komplett eigenen Text, aber einen Mindestanteil an einzigartigem, aus den echten Produktdaten abgeleitetem Inhalt, wenn sie eigenständig im Suchindex stehen soll. Google bewertet nicht die Erzeugungsmethode, sondern ob eine Seite Nutzern etwas bietet, das die nächsthöhere Kategorieseite nicht schon zeigt. Ein Absatz aus tatsächlichen Preisen, Mengen und Merkmalswerten dieser einen Kombination erfüllt das. Eine Vorlage, in die nur der Kategoriename eingesetzt wird, erfüllt es nicht.

Was passiert, wenn ein Sprachmodell in einer generierten Landingpage einen Preis oder eine Verfügbarkeit falsch angibt?

Ein Sprachmodell, das in einer generierten Landingpage einen Preis oder eine Verfügbarkeit falsch angibt, erzeugt eine Seite, die von den echten Shopdaten abweicht, sobald sich Preis oder Bestand im Shop ändern oder wenn das Modell den Wert von Anfang an falsch übernommen hat. Das ist mehr als ein Textfehler: Falsche Preisangaben können gegen die Preisangabenverordnung verstoßen, und eine falsche Verfügbarkeit führt zu Bestellungen, die der Shop nicht erfüllen kann. Die Gegenmaßnahme ist ein automatischer Abgleich nach jeder Textgenerierung, der jede im Absatz genannte Zahl mit dem Ausgangsfeld aus der API-Antwort vergleicht und den Absatz bei einer Abweichung verwirft, statt ihn zu veröffentlichen.

Woran unterscheidet sich eine automatisiert erzeugte PrestaShop-Landingpage von einer verbotenen Scaled-Content-Seite?

Eine automatisiert erzeugte PrestaShop-Landingpage unterscheidet sich von einer verbotenen Scaled-Content-Seite durch den Anteil an Information, der aus echten, sich zwischen den Seiten unterscheidenden Daten stammt. Googles Richtlinie gegen automatisiert erzeugten Masseninhalt stellt auf den Zweck der Seite ab: Seiten, die vor allem erzeugt wurden, um in der Suche zu ranken, ohne Nutzern einen eigenen Wert zu bieten, verstoßen dagegen. Eine Landingpage mit einer echten, ausreichend großen Produktgruppe, einer daraus abgeleiteten Preisspanne und einem Absatz, der genau diese Zahlen nennt, bietet diesen Wert. Eine Seite, die nur den Kategorienamen austauscht und sonst identisch ist, bietet ihn nicht.

Quellen

  1. PrestaShop Developer Documentation: Webservice, Getting Started, PrestaShop, abgerufen am 2026-08-26
  2. PrestaShop Developer Documentation: Zugriff auf den Webservice anlegen, PrestaShop, abgerufen am 2026-08-26
  3. Google Search Central: Spam-Richtlinien, Scaled Content Abuse, Google Search Central, abgerufen am 2026-08-26
  4. Google Search Central: Crawling von Facettennavigation verwalten, Google Search Central, abgerufen am 2026-08-26

Der Content wurde mit Hilfe von KI erstellt, vor allem in der Recherche und Vorformulierung. Prüfung und Abnahme durch unsere Redaktion.