Google AdWords API – Teil 3
Anzeigen und Keywords – mm dritten Teil der Google AdWords Artikelreihe geht es um Anzeigen, Keywords und Placements.
Anzeigen
Anzeigen kann man mit dem AdGroupAdService auslesen. Anders als bei Kampagnen und Anzeigegruppen hat man hier nun auch die Zahlen, für die man sich eigentlich interessiert. Auslesen kann man unterschiedliche Dinge, die wichtigsten sind:
- Klicks
- Impressionen
- CPC (Cost per Click)
- Conversions
- CTR (Click trough rate)
- Position
- …
Die vollständige Liste aller Werte ist hier zu finden.
So lese ich die Werte der Anzeigen aus:
function GetTextAds(AdWordsUser $user, $adGroupId, $days, $adwords_version) { // Get the service, which loads the required classes. $adGroupAdService = $user->GetService('AdGroupAdService', $adwords_version); // Create selector. $selector = new Selector(); $selector->fields = array('Headline', 'Id', 'Description1', 'Description2', 'DisplayUrl', 'Url', 'Status', 'AverageCpc', 'AveragePosition', 'Clicks', 'Conversions', 'Cost', 'Ctr', 'Impressions'); $selector->ordering[] = new OrderBy('Headline', 'ASCENDING'); // Create predicates. $selector->predicates[] = new Predicate('AdGroupId', 'IN', array($adGroupId)); $selector->predicates[] = new Predicate('AdType', 'IN', array('TEXT_AD')); // By default disabled ads aren't returned by the selector. To return them // include the DISABLED status in a predicate. $selector->predicates[] = new Predicate('Status', 'NOT_IN', array('DISABLED', 'PAUSED')); $selector->predicates[] = new Predicate('Impressions', 'GREATER_THAN', array('1')); $dateRange = new DateRange(); $str1 = '-1 days'; $str2 = '-1 days'; if($days > 0) { $str1 = '-'.$days.' days'; $str2 = '-'.$days.' days'; } $dateRange->min = date('Ymd', strtotime($str1)); $dateRange->max = date('Ymd', strtotime($str2)); $selector->dateRange = $dateRange; // Create paging controls. $selector->paging = new Paging(0, AdWordsConstants::RECOMMENDED_PAGE_SIZE); $ret = array(); do { // Make the get request. $page = $adGroupAdService->get($selector); // Display results. if (isset($page->entries)) { foreach ($page->entries as $adGroupAd) { $cr = 0; if($adGroupAd->stats->clicks > 0) $cr = $adGroupAd->stats->conversions / $adGroupAd->stats->clicks; $ret[] = array( 'headline' => $adGroupAd->ad->headline, 'id' => $adGroupAd->ad->id, 'textrow1' => $adGroupAd->ad->description1, 'textrow2' => $adGroupAd->ad->description2, 'view_url' => $adGroupAd->ad->displayUrl, 'target_url' => $adGroupAd->ad->url, 'active' => (strcmp($adGroupAd->status,'ENABLED')==0)?1:0, 'clicks' => $adGroupAd->stats->clicks, 'cpc' => $adGroupAd->stats->averageCpc->microAmount / 1000000, 'conversions' => $adGroupAd->stats->conversions, 'cost' => $adGroupAd->stats->cost->microAmount / 1000000, 'ctr' => $adGroupAd->stats->ctr, 'impressions' => $adGroupAd->stats->impressions, 'cr' => $cr, 'position' => $adGroupAd->stats->averagePosition ); } } else { //print "No text ads were found.\n"; } // Advance the paging index. $selector->paging->startIndex += AdWordsConstants::RECOMMENDED_PAGE_SIZE; } while ($page->totalNumEntries > $selector->paging->startIndex); return $ret; }
Neu ist hier, dass ich im Selector eine dateRange angebe. In diesem Beispiel übergebe ich die Variable days, welche angibt, den wievielten Tag in der Vergangenheit geholt werden soll. Es wird so genau eine Zeile Daten für einen Tage geliefert. Hier kann man natürlich auch Zeitspannen angeben (zum Beispiel eine Woche). Dann bekommt man die Werte auf eine Woche aufsummiert.
Eine Anzeige wird über folgende Werte definiert:
- Headline
Die Überschrift der Textwerbung. - Description1
Die erste Zeile der Textwerbung. - Description2
Die zweite Zeile. - DisplayUrl
Die angezeigte Url. - Url
Die Url die hinterlegt ist.
Keywords/Placements
Keywords und Placements holt man sich mit dem selben Service: dem AdGroupCriterionService. Hier der Code wie ich mir die Keywords hole. Dieser entspricht fast zur Gänze dem Code für die Anzeigen:
function GetKeywords(AdWordsUser $user, $adGroupId, $days, $adwords_version) { // Get the service, which loads the required classes. $adGroupCriterionService = $user->GetService('AdGroupCriterionService', $adwords_version); // Create selector. $selector = new Selector(); $selector->fields = array('KeywordText', 'KeywordMatchType', 'Id', 'AverageCpc', 'AveragePosition', 'Clicks', 'Conversions', 'Cost', 'Ctr', 'Impressions', 'QualityScore', 'Status'); $selector->ordering[] = new OrderBy('KeywordText', 'ASCENDING'); // Create predicates. $selector->predicates[] = new Predicate('AdGroupId', 'IN', array($adGroupId)); $selector->predicates[] = new Predicate('CriteriaType', 'IN', array('KEYWORD')); $selector->predicates[] = new Predicate('Status', 'IN', array('ACTIVE')); $selector->predicates[] = new Predicate('Impressions', 'GREATER_THAN', array('1')); $dateRange = new DateRange(); $str1 = '-1 days'; $str2 = '-1 days'; if($days > 0) { $str1 = '-'.$days.' days'; $str2 = '-'.$days.' days'; } $dateRange->min = date('Ymd', strtotime($str1)); $dateRange->max = date('Ymd', strtotime($str2)); $selector->dateRange = $dateRange; // Create paging controls. $selector->paging = new Paging(0, AdWordsConstants::RECOMMENDED_PAGE_SIZE); $ret = array(); do { // Make the get request. $page = $adGroupCriterionService->get($selector); // Display results. if (isset($page->entries)) { foreach ($page->entries as $adGroupCriterion) { $cr = 0; if($adGroupCriterion->stats->clicks > 0) $cr = $adGroupCriterion->stats->conversions / $adGroupCriterion->stats->clicks; $ret[] = array( 'name' => $adGroupCriterion->criterion->text, 'type' => $adGroupCriterion->criterion->matchType, 'id' => $adGroupCriterion->criterion->id, 'clicks' => $adGroupCriterion->stats->clicks, 'cpc' => $adGroupCriterion->stats->averageCpc->microAmount / 1000000, 'conversions' => $adGroupCriterion->stats->conversions, 'cost' => $adGroupCriterion->stats->cost->microAmount / 1000000, 'ctr' => $adGroupCriterion->stats->ctr, 'impressions' => $adGroupCriterion->stats->impressions, 'qualityfactor' => $adGroupCriterion->qualityInfo->qualityScore, 'cr' => $cr, 'position' => $adGroupCriterion->stats->averagePosition ); } } else { //print "No keywords were found.\n"; } // Advance the paging index. $selector->paging->startIndex += AdWordsConstants::RECOMMENDED_PAGE_SIZE; } while ($page->totalNumEntries > $selector->paging->startIndex); return $ret; }
Für die Placements kann man zusätzlich zu diesen Daten noch den Namen und die Url holen.
Nun haben wir alles um die Daten aus AdWords abzufragen. Ich speichere mir die Tageswerte in einer Datenbank und berechne mir daraus gegebenenfalls wieder Wochen oder Monatswerte. Für die Kampagnen und Anzeigegruppen muss man die Summe aller Daten ihrer Keywords, Placements und Anzeigen zusammenzählen.
Soweit mein Ausflug in die Welt von Google und der AdWords API. Ich freue mich auf Kommentare!
Teil 1 | Teil 2 | Teil 3 | Teil 4 | Teil 5 | Teil 6
HI,
danke nochmal für dieses tollte Tutorial. Wie schaffe ich es denn, die Keywords und deren Metriken von EINER Kampagne auszugeben? Ich kann zwar statt der AdGroupId die CampaignID verwenden, bekomme als Ergebnis aber jedes Keyword so oft, wie es in den verschiedenen AdGroups vorkommt (also Leberwurst samt Daten für Adgroup1 und Leberwurst samt Daten in Adgroup2, Muss ich die nun selbst per php gruppieren oder gibt es dazu noch einen Trick?
Danke für jeden Hinweis
Michael
Hallo, also für mein Projekt war genau das wichtig! Bei der Anzeige habe ich die Keywords dann auch mit Kampagne und Adgroup ausgegeben, also zB Leberwurst zig mal 😉 Natürlich macht es auf Kampagnenebene Sinn Keywords nur einmal auszugeben. Da solltest du die Keywords nach Adwords Keyword ID gruppieren (die haben dann doch die gleiche nehm ich an?) Hilft dir das weiter? Wenn nicht kann ich mir das gerne noch mal genauer ansehen.
Hi, tolles Tutorial! Ich möchte alle rechnungsrelevanten Daten (Klicks) 1x wöchentlich auslesen und in eine MySQL DB importieren. Anschließend meinen Kunden auf Basis der Daten eine Rechnung stellen. Leider kann ich keine Adjustments (invalide) Klicks Abfragen bzw. sind die Daten nicht enthalten. Hast Du eine Idee?
Hey, was genau verstehst du unter invalide Klicks? Sind das die Klick die Google später mit deren fraud detection wieder entfernt?
Hi, ja genau die meine ich.
Gruß Tom
mit dem Problem kämpfe ich auch. Ich hab das im 6. Teil der Artikelserie beschrieben. Was ich bis jetzt weiß ist, dass Google Daten bis zu einem Monat lang durch dieses Vorgehen ändern kann. Leider habe ich aber noch keine Möglichkeit gefunden dagegen etwas zu machen. Einziger Lösungsansatz: die Daten sind erst mit einem Monat Verspätung korrekt. D.h. wenn du das rausfinden möchtest merkst du dir die Klicks von gestern…und wenn du in einem Monat die Daten vom gestrigen Tag nochmals einspielst kannst du an der Differenz der Klicks die Änderung erkennen.
Für mein Projekt ist das aber irrelevant, da wir täglich so viele Daten einlesen, dass der Import selbst fast 20 Stunden dauert 🙁
Ja macht in meinem Projekt wenig Sinn, da ich ja nicht erst 4 Wochen später die Rechnung an meine Kunden schick und jedesmal in Vorleistung gehen muss. Ich bin am Überlegen die Gutschriften dann manuell in die DB zu importieren und bei der nächsten Rechnung vom Gesamtbetrag abzuziehen. Ich finde die API verfehlt in diesem Punkt deutlich das Ziel da die Daten nicht 100% aktuell sind!
GetFraudKlicks() wäre eine interessante Methode 😉
Ja. Nur meines Wissens nach sind die Daten bis zu einem Monat lang „variabel“. Fraud detection ist wichtig, aber du hast Recht, das führt die API ad absurdum, da man ja somit nicht sichergehen kann, dass man korrekte Daten hat…
Ich habe Stunden nach dem Fehler gesucht, weil der Kunde immer über falsche Daten geschimpft hat!
Warum soll es Dir anders gehen 😉
Ich hatte teilweise Abweichungen von mehreren Hunderten Euros und manche Kunden drohen verständlicherweise mit Kündigung! Zur Zeit mach ich das manuell. Wenn ich die Rechnung von Google erhalten habe übernimm ich die Daten und schick die Rechnungen dann meinen Kunden. Das ist alles andere als zeitgemäß und du kannst Dir vorstellen wieviel Zeit ich verplempere mit dem Empfang und Senden von Mahnungen!
oje
Kurze Anmerkung: Mit der BING API funktioniert alles wunderbar! Da gibt es vielleicht mal Abweichungen von 5 oder 10 Euro die aber letzten Endes wirklich keinem wehtun und einfach in die nächste Rechnung fließen.
ah danke für die Info. Mit der hab ich noch keine Erfahrung…lohnt sich anscheinend da mal reinzuschauen.
Hey,
erst einmal danke!
Dein Tutorial hier hat mir schon sehr geholfen.
Ich habe da aber noch eine Frage.
Für mein Projekt versuche ich die Statistik-Daten der Anzeigen auszulesen. Es ist jedoch so, dass ich in einer Anzeigengruppe für jede Anzeige die gleichen Daten bekomme, was ja nicht stimmt.
Ich hätte es gerne so, dass für jede Anzeige, für jedes Keyword, das zu mindestens einer Impression für die Anzeige geführt hat ein neuer Datensatz angelegt wird.
Hast Du da vielleicht eine Idee?
Hallo, das klingt so als wäre da irgendwo ein Fehler! Über meinen Adwords Code lese ich Daten von zahlreichen Kunden schon über Monate und so etwas wäre mir noch nicht aufgefallen. Schau mal ob du das Problem findest. Ansonsten kann ich dir nur anbieten, dass ich eventuell mal über den Code schau ob mir da was auffällt.
Hey,
danke für deine Antwort. Ich habe das jetzt ein bisschen anders gelöst.
Aber ich habe trotzdem noch eine Frage. Wie kann man den Kampagnen, die im Display-Netzwerk angezeigt werden rausfiltern?
Die liefern mir nämlich immer wenn ich die Statistiken zu den (hier nicht vorhandenen) Keywords abrufe ein leeres Array.
Und ich will eigentlich nur Informationen über die Kampagnen mit Keywords als Kriterium haben.