Exploration mit DSA und Broad-Match in Google Ads. Aber sinnvoll.

Draufsicht auf Hände, die blanke Karten auf einem hellen Tisch in zwei Gruppen sortieren.

Bildhinweis: KI-generiert

Von Nick Martens. Veröffentlicht am 13.10.2026

Wir wissen alle, dass Google seit Jahren die Match-Types zunehmend aufweicht und somit Exact- und Phrase-Match nicht mehr das sind, was sie mal waren bzw. was ihre Bezeichnung vermuten lässt. Search-Terms müssen genauer und häufiger überprüft werden. Auch wenn man nur Exakt- und Phrase-Match verwendet. Broad-Match dreht komplett durch und von AI Max möchte ich gar nicht erst anfangen.

Nichtsdestotrotz kann es natürlich sinnvoll sein über den Tellerrand des aktuellen Keyword-Sets hinauszuschauen und neue relevante Suchthemen zu suchen. Aber wie kann man das sauber machen, ohne dass Broad-Match-Keywords und DSAs das aktuelle Setup kannibalisieren?

Die Lösung ist einfach. Wir übernehmen einfach alle aktiven Exact- und Phrase-Keywords als Negatives in Listen. Dies kann es zwar nicht ganz vermeiden – positive und negative Match-Types sind nicht identisch – aber minimieren.[1] Das Vorgehen ist:

1. Eigene Kampagne(n) für Broad-Match und DSA

Da wir Negative-Listen nur auf Kampagnen-Ebene ausschliessen können müssen wir für die Exploration eine oder mehrere eigene Kampagnen erstellen. Je nach Bedarf. Könnte auch so sinnvoll sein, da für die Exploration ein anderes Bidding, als für die Exploitation, empfehlenswert ist.

2. Negative-Listen erstellen

Wir erstellen zwei Listen. Diese müssen ‚Alle aktiven KWs (e) automated‘ und ‚Alle aktiven KWs (p) automated‘ heißen. Ihr könnt sie natürlich auch umbenennen, dann aber bitte auch die Namen im Skript ändern. Außerdem muss bei der Erstellung ein Platzhalter-Keyword hinzugefügt werden. Leere Listen lassen sich nicht erstellen. Schliesst eben diese Listen dann in den entsprechenden Exploration-Kampagnen aus.

Die Unterteilung der Listen in Exact- und Phrase-Match lässt es theoretisch zu aus Phrase-Kampagnen alle Exact-Keywords auszuschließen. Das könnt ihr machen. Ich hab sowas allerdings seit 2020 nicht mehr gesehen.

3. Das erste Skript einbinden

Die Listen wollen befüllt werden. Hierfür fügt unter Tools > Bulk-Aktionen > Skripts ein neues Skript hinzu, gebt ihm einen schmissigen Namen und fügt diesen Code hinzu:

function main() {
  var listE = findList("Alle aktiven KWs (e) automated");
  var listP = findList("Alle aktiven KWs (p) automated");

  if (!listE || !listP) {
    throw new Error("Negativliste(n) nicht gefunden. Namen prüfen oder Listen anlegen.");
  }

  var it = AdsApp.keywords()
    .withCondition("Status = ENABLED")
    .withCondition("AdGroupStatus = ENABLED")
    .withCondition("CampaignStatus = ENABLED")
    .get();

  var seen = {};
  var added = 0, skipped = 0, errors = 0;

  while (it.hasNext()) {
    var kw = it.next();
    var type = kw.getMatchType();

    if (type !== "EXACT" && type !== "PHRASE") {
      skipped++;
      continue;
    }

    var text = kw.getText().trim();
    var key = type + "|" + text.toLowerCase();
    if (seen[key]) {
      skipped++;
      continue;
    }
    seen[key] = true;

    var list = (type === "EXACT") ? listE : listP;
    var neg = (type === "EXACT") ? "[" + text + "]" : "\"" + text + "\"";

    try {
      list.addNegativeKeyword(neg);
      added++;
    } catch (e) {
      errors++;
      Logger.log("Fehler bei " + neg + ": " + e);
    }
  }

  Logger.log("Hinzugefügt: " + added + " | Übersprungen: " + skipped + " | Fehler: " + errors);
}

function findList(name) {
  var it = AdsApp.negativeKeywordLists()
    .withCondition("Name = '" + name + "'")
    .get();
  return it.hasNext() ? it.next() : null;
}

Gebt dem Skript die benötigten Berechtigungen und macht einen Vorschau-Durchlauf. Im Protokoll sollte dann stehen wie viele Keywords den Listen hinzugefügt worden wären. Wenn das passt speichern und dem Skript gerne eine sinnvolle Frequency einstellen. Ich stelle es immer auf täglich zwischen 04:00 und 05:00.

4. Optional: Das zweite Skript einbinden

Es ist ja schön, dass jetzt immer alle neuen Keywords den Listen angefügt werden. Was ist aber, wenn Keywords pausiert oder entfernt werden? Diese können – müssen aber nicht – aus den Listen wieder herausgenommen werden. Sodass die Listen wirklich nur die aktiven Keywords abbilden. Sonst bilden sie alle ab, die aktiv sind oder es eben waren. Das müsst ihr entscheiden. Die Keywords fliegen ja aus einem Grund raus.

Wenn ihr das gerne möchtet, dann wiederholt den Schritt 3, fügt aber stattdessen diesen Code hinzu:

function main() {
  var listE = findList("Alle aktiven KWs (e) automated");
  var listP = findList("Alle aktiven KWs (p) automated");
  if (!listE || !listP) {
    throw new Error("Negativliste(n) nicht gefunden. Abbruch.");
  }

  var activeExact = {};
  var activePhrase = {};
  var activeCount = 0;

  var it = AdsApp.keywords()
    .withCondition("Status = 'ENABLED'")
    .withCondition("AdGroupStatus = 'ENABLED'")
    .withCondition("CampaignStatus = 'ENABLED'")
    .get();

  while (it.hasNext()) {
    var kw = it.next();
    var key = normalize(kw.getText());
    var type = kw.getMatchType();
    activeCount++;
    if (type === "EXACT") activeExact[key] = true;
    else if (type === "PHRASE") activePhrase[key] = true;
  }

  if (activeCount === 0) {
    throw new Error("Keine aktiven Keywords gefunden. Abbruch, damit keine Listen geleert werden.");
  }

  var toRemove = [];
  var staleE = collectStale(listE, "EXACT", activeExact, toRemove);
  var staleP = collectStale(listP, "PHRASE", activePhrase, toRemove);

  Logger.log("Aktive Keywords: " + activeCount);
  Logger.log("Zu entfernende Negative (exact): " + staleE);
  Logger.log("Zu entfernende Negative (phrase): " + staleP);

  var removed = 0;
  for (var i = 0; i < toRemove.length; i++) {
    try {
      toRemove[i].remove();
      removed++;
    } catch (e) {
      Logger.log("Fehler beim Entfernen: " + e);
    }
  }
  Logger.log("Entfernt: " + removed);
}

function collectStale(list, type, activeMap, out) {
  var count = 0;
  var it = list.negativeKeywords().get();
  while (it.hasNext()) {
    var neg = it.next();
    if (neg.getMatchType() !== type) continue;
    if (!activeMap[normalize(neg.getText())]) {
      out.push(neg);
      count++;
    }
  }
  return count;
}

function normalize(text) {
  return text.trim().toLowerCase();
}

function findList(name) {
  var it = AdsApp.negativeKeywordLists()
    .withCondition("Name = '" + name + "'")
    .get();
  return it.hasNext() ? it.next() : null;
}

Auch hier gerne wieder einen Vorschau-Lauf starten bevor ihr das Skript aktiv laufen lasst. Ich lasse das nach dem ersten Skript täglich zwischen 05:00 und 06:00 laufen.

Das war es dann auch schon. Jetzt habt ihr eine oder mehrere Kampagnen, deren Überschneidungen mit den anderen Suchkampagnen reduziert wurden. Da positive und negative Match-Types leider nicht deckungsgleich sind, müssen trotzdem Search-Terms gecheckt werden.

Wenn du zusätzlich noch Pmax-Kampagnen in deinem Konto hast, schau doch hier vorbei, um zu erfahren was du da machen kannst.

Wichtig: Negative Listen sind auf 5.000 Keywords beschränkt.[2] Solltet ihr mehr haben müsst ihr das Skript umschreiben (lassen) und mit mehreren Listen arbeiten. Aber da kann die KI euch sicher weiterhelfen. Außerdem sollten die Negative-Listen nicht darüber hinaus manuell bestückt werden. Diese Negatives würde das zweite Skript direkt wieder löschen. Erstellt dafür extra Listen.

Quellen

[1] Google Ads-Hilfe: „Auszuschließende Keywords“.
https://support.google.com/google-ads/answer/2453972 , abgerufen am 13.10.2026.
[2] Google Ads-Hilfe: „Listen mit auszuschließenden Keywords“.
https://support.google.com/google-ads/answer/2453983 , abgerufen am 13.10.2026.

Kommentare

Ein Kommentar zu „Exploration mit DSA und Broad-Match in Google Ads. Aber sinnvoll.“

  1. […] aktiven KWs (e) automated‘ und ‚Alle aktiven KWs (p) automated‘ aus dem anderen Artikel lassen sich direkt an die Pmax-Kampagne(n) hängen, die für Exploration zuständig sind (oder an […]

Consent Management Platform von Real Cookie Banner