...

Wie Sie mit Python und Bulk-Operationen die perfekte Amazon-Kampagnenstruktur erstellen

22.07.2022 • Lesezeit: ca. 11 min • von Trutz Fries

Dieser Artikel zeigt Ihnen, wie Sie die Programmiersprache Python und das Pandas-Paket nutzen können, um die Tabellen zu erstellen, die Sie für die Arbeit mit Amazons Bulk-Operationen benötigen.

Was sind Amazon Advertising Bulk-Operationen?

Amazon Advertising Bulk Operationen, auch Bulk Sheets oder Sammelvorgänge genannt, sind Excel-Tabellen, die Ihre komplette Kampagnenstruktur enthalten, einschließlich der relevanten Leistungskennzahlen.

Sie können entweder neue Kampagnen erstellen oder bestehende Kampagnen mit Bulk Sheets aktualisieren.

Die Seite, auf der Sie Bulk Sheets herunter- und hochladen können, finden Sie in der Amazon Advertising Console unter “Gesponsorte Anzeigen” / “Sammelvorgänge”:

Bulk-Operationen in der Amazon Advertising Console
Bulk-Operationen in der Amazon Advertising Console

Bulk Sheets sind besonders praktisch, wenn Sie z.B. mehrere Kampagnen erstellen oder aktualisieren wollen, ohne den gleichen Vorgang für jede Kampagne einzeln durchzuführen.

Nehmen wir an, Sie möchten das Budget für jede Ihrer 400 Sponsored Products-Kampagnen mit einem ACoS < 20 % um 10 % erhöhen. Zwar können Sie das problemlos in der Amazon-Werbekonsole machen, aber die Verwendung von Amazons Bulk Sheets ist wesentlich effizienter.

Sie verwenden Bulk Sheets folgendermaßen:

  1. Sie laden das aktuelle Bulk Sheet aus der Werbekonsole herunter
  2. Sie öffnen die Datei z.B. in Microsoft Excel und rufen das Arbeitsblatt "Gesponserte Produkte" auf
  3. Sie filtern nach den Kampagnen, die Sie bearbeiten möchten
  4. Sie verändern die Budgetspalte, indem Sie z.B. eine temporäre Spalte hinzufügen
  5. Sie speichern die Datei und laden sie erneut bei Amazon hoch

In diesem Artikel wollen wir uns allerdings nicht mit der Aktualisierung bestehender Kampagnen befassen, sondern mit der Erstellung neuer Kampagnen.

Wie sieht die perfekte Kampagnenstruktur aus?

Unsere Agentur REVOIC (opens new window) erstellt in der Regel sehr spezifische Kampagnen für einzelne Produkte oder Produktfamilien.

Wir erstellen z.B. typischerweise die folgenden manuellen Sponsored Product Kampagnen:

  • Eine Kampagne mit generischen Keyword-Zielen (generisch bedeutet, dass die Keywords keinen Markennamen enthalten)
  • Eine Kampagne mit offensiven Keyword-Zielen (offensiv bedeutet, dass wir auf die Marken der Konkurrenz abzielen)
  • Eine Kampagne mit offensiven Produktzielen (d. h., wir zielen auf die Produkte der Konkurrenz ab)
  • Eine Kampagne mit defensiven Keyword-Zielen (defensiv bedeutet, dass wir auf Keywords abzielen, die unsere Marken- oder Produktnamen enthalten)
  • Eine Kampagne mit defensiven Produktzielen (d. h. wir zielen auf unsere Produkte ab)

Wir unterscheiden die Kampagnen, weil offensive, generische und defensive Kampagnen in der Regel sehr verschiedene Leistungskennzahlen aufweisen. Bspw. ist es wesentlich "günstiger", auf Ihre Marke zu bieten als auf die Marken der Wettbewerber zu bieten. Generische Kampagnen sind in der Regel weniger "teuer" als "offensive" Kampagnen, dafür aber “teurer” als "defensive" Kampagnen. Das bedeutet, dass Sie für jeden Typ unterschiedliche Leistungsziele haben müssen. Wenn der ACoS Ihr Hauptziel ist, benötigen Sie für offensive Kampagnen höhere ACoS-Ziele als für defensive Kampagnen.

Packen Sie alle Ziele in einem Kampagne, dann haben Sie eine gemischte Tüte. Natürlich können Sie diese Kampagne z.B. auf Zielebene verwalten, aber wie würden Sie dann das Budget zuweisen? Wie würden Sie z.B. höhere Budgets für Ihre defensiven Kampagnen als für Ihre offensiven Kampagnen zulassen? Das wäre nicht möglich. Das ist ein weiterer Grund, warum wir Kampagnen aufteilen.

Die Erstellung von fünf Kampagnen für ein einziges Produkt bzw. für eine einzige Produktfamilie erfordert jedoch einige Arbeit. Und genau hier automatisieren wir die Dinge mit Python.

Wie erstelle ich ein neues Bulk Sheet mit Python?

Zur Erstellung eines neuen Bulk Sheets, das sinnvolle Kampagnen für ein bestimmtes Produkt erstellt, benötigen wir zunächst folgende Informationen:

  • Welche ASINs oder SKUs sollen beworben werden?
  • Von welchen Marken sind Sie Inhaber und wie heißen die Marken der Konkurrenz?
  • Auf welche Keywords möchten Sie abzielen?
  • Welche Produkte möchten Sie bewerben?

Organisieren Sie diese Informationen, z.B. in einem anderen Excel-Sheet oder Google Docs. Wir organisieren diese Informationen in separaten Textdateien. Wir haben andere Skripte, die diese Textdateien mehr oder weniger automatisch erstellen, z.B. aus bestehenden (aber unorganisierten) Kampagnen, aber das müssen wir in einem anderen Beitrag besprechen.

Produkt- und Keyword-Daten werden in verschiedenen Textdateien gespeichert
Produkt- und Keyword-Daten werden in verschiedenen Textdateien gespeichert

Wir erstellen diese Dateien für jede ASIN, SKU oder Gruppe von ASINs/SKUs.

Unser Skript durchläuft dann jeden Ordner und erstellt diese fünf Kampagnen für jedes Produkt (jede Gruppe). Das Einzige, was Sie tun müssen, ist, diese Dateien zu füllen, das Skript auszuführen, das Bulk Sheet hochzuladen, und schon können Sie loslegen.

Hier sehen Sie die wichtigsten Bestandteile des Skripts. Es würde zuviel Platz beanspruchen, jede einzelne Zeile des Codes zu zeigen, daher konzentrieren wir uns auf die wichtigsten Dinge.

Einrichten einiger Variablen

Da wir ein neues Bulk Sheet erstellen werden, müssen wir die Struktur des Bulk Sheets mit seinen verschiedenen Entitäten verstehen. Sie müssen für eine Kampagne andere Werte definieren, als für eine Anzeigen- oder eine Keyword-Gruppe.

Um eine neue Kampagne zu erstellen, müssen Sie die folgenden Felder ausfüllen (Sie finden diese, wenn Sie z.B. ein ausgefülltes Datenblatt herunterladen):

emptySpBulksheet = {
   "Product": "Sponsored Products",
   "Entity": "",
   "Operation": "Create",
   "Campaign Id": "",
   "Ad Group Id": "",
   "Portfolio Id": "",
   "Ad Id (Read only)": "",
   "Keyword Id (Read only)": "",
   "Product Targeting Id (Read only)": "",
   "Campaign Name": "",
   "Ad Group Name": "",
   "Start Date": "",
   "End Date": "",
   "Targeting Type": "",
   "State": "",
   "Daily Budget": "",
   "SKU": "",
   "ASIN": "",
   "Ad Group Default Bid": "",
   "Bid": "",
   "Keyword Text": "",
   "Match Type": "",
   "Bidding Strategy": "",
   "Placement": "",
   "Percentage": "",
   "Product Targeting Expression": ""
}

Das sind die Spalten, die ausgefüllt werden müssen. Einige Spalten gehören zu speziellen Entitäten, z.B. bezieht sich die Spalte "Daily Budget" (tägliches Budget) nur auf die Entität "Campaign" (Kampagne).

Das Gleiche gilt z.B. für die Kampagnen Sponsored Brands und Sponsored Display.

Anschließend definieren wir einige Variablen, die das Verhalten unseres Skripts festlegen. Hier sind einige Beispiele:

# Campaign
createSPCampaigns = True
campaignStatus = "Enabled" # Enter “Enabled”, “Paused”, or “Archived”
campaignDailyBudget = 20 # EUR or USD
campaignBiddingStrategy = 'Dynamic bids - down only' # Enter "Dynamic bids - down only", "Dynamic bids - up and down", or "Fixed bid".
campaignStartDate = time.strftime("%Y%m%d") # Today as default, e.g. "20220529"
campaignEndDate = "" # “yyyymmdd”, can be empty

# Adgroup (https://advertising.amazon.com/API/docs/en-us/bulk sheets/sp/sp-entities/sp-entity-ad-group)
adgroupMaxBix = 1.50
adgroupStatus = "Enabled" # Enter “Enabled”, “Paused”, or “Archived”

# Keyword
keywordDefaultMatchType = 'broad'
negativeKeywordDefaultMatchType = 'negativeExact' # negativePhrase or negativeExact

# Toggles: Here you can define which type of targets to create (true) or not (false)
addKeywordsGeneric   = True
addKeywordsDefensive = True
addKeywordsOffensive = False
addProductsOffensive = False
addProductsDefensive = False

Dasselbe gilt für die anderen Anzeigearten (Sponsored Brands, Sponsored Display).

Zusätzliche Informationen für externe Datenblätter

Manchmal verwenden wir auch ein Excel-Blatt mit zusätzlichen Informationen. Das machen wir für unsere Mitarbeiter. In manchen Fällen kann es einfacher sein, mit Excel zu arbeiten anstatt mit Textdateien.

Nehmen wir an, wir haben ein separates Datenblatt, dessen Dateiname in der Variable mainInputFile gespeichert ist, mit zwei Blättern:

  • Unsere Marken und Produktnamen
  • Marken und Produktnamen der Wettbewerber

Um diese Marken in unser Python-Skript zu übertragen, müssen wir folgendes tun:

# Read additional data from main input file (Google Doc -> Excel Sheet)
xls = pd.ExcelFile(mainInputFile)
dfB = pd.read_excel(xls, engine="openpyxl", sheet_name="Our brands")
dfC = pd.read_excel(xls, engine="openpyxl", sheet_name="Competitor brands")

ownBrands        = dfB['Brand'].unique().tolist()
competitorBrands = dfC['Brand'].unique().tolist()

# Make sure brands are lowercase
ownBrands = list(map(str.lower, ownBrands))
competitorBrands = list(map(str.lower, competitorBrands))

Zusätzlich führen wir eine Datenmassage durch und konvertieren alles in Kleinbuchstaben. Das erleichtert den späteren Vergleich.

Sie könnten das auch fest in das Skript kodieren, aber dieser Ansatz macht es flexibler, was praktisch ist, wenn Sie mit mehreren Kunden arbeiten, wie wir es tun.

Methoden zur Erstellung von Kampagnen, Anzeigengruppen, usw.

Im nächsten Schritt müssen wir einige Funktionen/Hilfsmethoden definieren, um das Bulk Sheet zu erstellen.

Hier sehen Sie ein Beispiel für die Erstellung strukturierter Kampagnennamen, die auch das Ziel der Kampagne widerspiegeln:

def getCampaignName(targeting = "Manual", campaignType = "SP", type1="keyword", type2 = "generic", groupName = "default" ):
  
   prefix = "RE-" + campaignType + "-"
  
   # targeting
   if targeting == "Manual":
       targetingPrefix = "MANU-"
   else:
       targetingPrefix = "AUTO-"
      
   # type1
   if type1 == "keyword":
       type1Prefix = "KW-"
   else:
       type1Prefix = "PT-"
  
   # type 2
   if type2 == "generic":
       type2Prefix = "GEN-"
   elif type2 == "offensive":
       type2Prefix = "OFF-"
   else:
       type2Prefix = "DEF-"
  
   groupName = groupName.strip()
   groupName = groupName[:30].upper()
  
   campaignName = prefix + targetingPrefix + type1Prefix + type2Prefix + groupName + '-' + randomString
  
   return campaignName

Um unsere Kampagnen schnell identifizieren zu können, beginnen unsere Kampagnennamen mit einem Präfix. Danach fügen wir die folgenden Zeichenfolgen hinzu:

  • "MANU" oder "AUTO", wenn es sich um eine manuelle oder automatische Kampagne handelt (nur für Sponsored Product-Kampagnen)
  • "KW" oder "PT", wenn es sich um Keyword- oder Produkt-Targeting handelt
  • "GEN", "OFF" oder "DEF", um die Art der Zielsetzung zu unterscheiden (generisch, offensiv oder defensiv)
  • Der Name des Produkts (Gruppe)
  • Eine zufällige Zeichenfolge, die sich bei jeder Ausführung des Skripts ändert

Die zufällige Zeichenfolge macht es einfacher, z.B. nach Kampagnen zu filtern, die in einem einzigen Durchgang erstellt wurden. Bei Fehlern können Sie diese Kampagnen leicht finden und sie z.B. archivieren und neu beginnen. Lassen Sie das nicht weg. Sie werden es mir später danken.

Anschließend erstellen wir die verschiedenen Methoden zur Erstellung einer Entität, z.B. hier eine Methode zum Ausfüllen der relevanten Felder, die zur Erstellung einer Kampagne benötigt werden:

def createSpCampaign(targeting = "Manual", type1="none", type2 = "none", groupName = "none", customerPath = "none", counter = 1, fileName = "" ):

   global bulkSheetSp
  
   campaignName = getCampaignName(targeting = targeting, campaignType = "SP", type1=type1, type2 = type2, groupName = groupName)
  
   campaign = copy.deepcopy(emptySpBulksheet) # Create a deep copy
  
   campaign['Entity']           = 'Campaign'
   campaign['Campaign Id']      = campaignName
   campaign['Campaign Name']    = campaignName
   campaign['Start Date']       = campaignStartDate
   campaign['End Date']         = campaignEndDate
   campaign['Targeting Type']   = targeting.upper()
   campaign['State']            = campaignStatus
   campaign['Daily Budget']     = campaignDailyBudget
   campaign['Bidding Strategy'] = campaignBiddingStrategy
  
   if ((bulkSheetSp['Entity'] == 'Campaign') & (bulkSheetSp['Campaign Id'] == campaignName)).any():
       pass # Do nothing, we already have this campaign
   else:
       bulkSheetSp = bulkSheetSp.append(campaign, ignore_index=True)
  
   # Create adgroup         
   createSpAdgroup(targeting = targeting, type1=type1, type2 = type2, groupName = groupName, campaignName = campaignName, customerPath = customerPath, counter = counter, fileName = fileName)

Hierein kopieren wir zunächst unser "leeres Bulk Sheet" und füllen es mit allen erforderlichen Daten aus. Woher diese kommen, werden Sie später sehen. Diese Methode ruft dann die nächste Methode createSpAdgroup auf, die einen ähnlichen Vorgang wie oben gezeigt durchführt, nur für eine Anzeigengruppe. Alle Informationen, die wir an unsere Kampagne übergeben haben, werden auch an die Anzeigengruppe weitergegeben.

Diese Methode sieht wie folgt aus:

def createSpAdgroup(targeting = "Manual", type1="none", type2 = "none", groupName = "none", campaignName = 'none', customerPath = "none", counter = 1, fileName = ""):
  
   counterString = f"{counter:02}"
  
   global bulkSheetSp
  
   adgroupName  = getCampaignName(targeting = targeting, campaignType = "SP", type1=type1, type2 = type2, groupName = groupName) + '-AG' + '-' + counterString
  
   adgroup = copy.deepcopy(emptySpBulksheet) # Create a deep copy to not alter emptySpBulksheet
  
   adgroup['Entity']        = 'Ad Group'
   adgroup['Campaign Id']   = campaignName
   adgroup['Ad Group Name'] = adgroupName
   adgroup['Ad Group Id']   = adgroupName
   adgroup['State']         = adgroupStatus
   adgroup['Ad Group Default Bid'] = adgroupMaxBix
      
   bulkSheetSp = bulkSheetSp.append(adgroup, ignore_index=True)

   # Create ad
  
   createSpAd(targeting = targeting, type1=type1, type2=type2, groupName=groupName, campaignName=campaignName, adgroupName=adgroupName, customerPath = customerPath)
  
   if type1 == "keyword":
       createSpKeywordTarget(targeting = targeting, type1=type1, type2=type2, groupName=groupName, campaignName=campaignName, adgroupName=adgroupName, customerPath = customerPath, fileName = fileName)

   if type1 == "product":
       createSpProductTarget(targeting = targeting, type1=type1, type2=type2, groupName=groupName, campaignName=campaignName, adgroupName=adgroupName, customerPath = customerPath)

Alle anderen Methoden, die zur Erstellung von Anzeigen, Keyword-Zielen, Produktzielen, negativen Keywords usw. benötigt werden, definieren wir auf dieselbe Weise.

Die Hauptmethode, die alles in Gang setzt

Schließlich benötigen wir unser Hauptskript, um das Ganze in Gang zu setzen. Das sieht folgendermaßen aus:

if createSPCampaigns:
  
   # Create empty bulksheet
   bulkSheetSp = pd.DataFrame(data=emptySpBulksheet, index=[0])

   # Get all products or product groups stored in different folders
   productGroups = list_paths(customerPath)
   productGroupsLength = len(productGroups)

   j = 0

   randomString = randStr(N=5) # Create a random string

   for productGroup in productGroups:
      
       j = j + 1
      
       # Check which files are available
       all_files = sorted(glob.glob(customerPath  + '/' + productGroup + '/*.txt'))
      
       counter = 0

       for file in all_files:

           if (addKeywordsOffensive) & ('keywords-offensive.txt' in file):
               createSpCampaign(targeting = "Manual", type1="keyword", type2 = "offensive", groupName = productGroup, customerPath = customerPath, fileName = file)
          
           if (addKeywordsGeneric == True) & ('keywords-generic.txt' in file):
               counter = counter + 1
               createSpCampaign(targeting = "Manual", type1="keyword", type2 = "generic", groupName = productGroup, customerPath = customerPath, counter = counter, fileName = file)
          
           if (addKeywordsDefensive) & ('keywords-defensive.txt' in file):
               createSpCampaign(targeting = "Manual", type1="keyword", type2 = "defensive", groupName = productGroup, customerPath = customerPath, fileName = file)
          
           if (addProductsDefensive) & ('products-defensive.txt' in file):
               createSpCampaign(targeting = "Manual", type1="product", type2 = "defensive", groupName = productGroup, customerPath = customerPath, fileName = file)
          
           if (addProductsOffensive) & ('products-offensive.txt' in file):
               createSpCampaign(targeting = "Manual", type1="product", type2 = "offensive", groupName = productGroup, customerPath = customerPath, fileName = file)

Aus didaktischen Gründen habe ich einige Zeilen entfernt, z.B. um die Dateien zu säubern, bevor wir sie analysieren (leere Zeilen entfernen, doppelte Schlüsselwörter entfernen usw.). Unser Skript behandelt auch den Fall, dass eine Datei mehr als 1.000 Schlüsselwörter enthält. Das kann schnell passieren, wenn Sie mit Permutationen arbeiten, weil Sie Phrase-Match (Passende Wortgruppe) im Falle von Broad-Match (Weitgehend passend) verwenden wollen.

Erstellung des Amazon Bulk Sheets

Zu guter Letzt müssen wir unsere Daten in eine Excel-Tabelle exportieren, die wir dann bei Amazon hochladen können.

Das funktioniert folgendermaßen:

# Remove empty rows
if createSPCampaigns:
   bulkSheetSp['Entity'].replace('', np.nan, inplace=True)
   bulkSheetSp.dropna(subset=['Entity'], inplace=True)

# Filename
today = time.strftime("%Y-%m-%d-%H-%M") # Today as default
outputFile = customerPath + '/' + today + '-' + slugify(customer) + '-campaign-create-bulksheet.xlsx'
outputFile = outputFile.replace("input-", "")

# Export to Excel
with pd.ExcelWriter(outputFile) as writer: 
   if createSPCampaigns:
       bulkSheetSp.to_excel(writer, sheet_name='Sponsored Products Campaigns', index=False)

Fazit

Haben Sie einmal alles vorbereitet, können Sie die txt-Dateien oder Ihr Haupteingabeblatt schnell mit Daten füllen

Hier sind einige Ideen, die Ihnen den Einstieg erleichtern:

Wenn Ihr Kunde uns den Auftrag erteilt, die bestehenden Kampagnen neu zu organisieren und die gut funktionierenden Keywords zu nutzen, analysieren wir z.B. die bestehenden Bulk Sheets und extrahieren alle Produkte einschließlich der gut funktionierenden Ziele. Anschließend ordnen wir jedes Ziel in den richtigen Bereich ein und führen das Skript innerhalb weniger Minuten aus.

Verwandte Artikel
Fehlende Amazon Listing Keywords mit Hilfe von Brand Analytics ermitteln

Blog

Fehlende Amazon Listing Keywords mit Hilfe von Brand Analytics ermitteln

So finden Sie auf Knopfdruck fehlende Amazon Keywords aus Amazon Brand Analytics

Trutz Fries

Amazon Rezensionen mit BERTopic und Python analysieren

Blog

Amazon Rezensionen mit BERTopic und Python analysieren

Amazon Rezensionen mit BERTopic analysieren

Trutz Fries

Brauchen Sie mehr Übersicht auf Amazon?
14 Tage kostenlos testen
Haben Sie noch Fragen? Rufen Sie uns an!
Tel. 0221-29 19 12 32 | info@amalytix.com