Codebeispiel für Schlüsselwortplaner

In diesem Beispiel wird veranschaulicht, wie Sie Schlüsselwort (keyword) Ideen und Datenverkehrsschätzungen für Suchwerbekampagnen erhalten.

Tipp

Verwenden Sie die Sprachauswahl im Dokumentationsheader, um C#, Java, Php oder Python auszuwählen.

Informationen zum Abrufen von Zugriffs- und Aktualisierungstoken für Ihren Microsoft Advertising-Benutzer und Zum ersten Dienstaufruf mithilfe der Bing Ads-API finden Sie im Schnellstarthandbuch . Sie sollten den Leitfaden für die ersten Schritte und exemplarische Vorgehensweisen für Ihre bevorzugte Sprache lesen, z. B. C#, Java, Php und Python.

Unterstützende Dateien für C#-, Java-, Php- und Python-Beispiele sind auf GitHub verfügbar. Sie können jedes Repository klonen oder Codeausschnitte nach Bedarf erneut verwenden.

using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Threading.Tasks;
using Microsoft.BingAds.V13.AdInsight;
using Microsoft.BingAds;

namespace BingAdsExamplesLibrary.V13
{
    /// <summary>
    /// How to get keyword ideas and traffic estimates for search advertising campaigns.
    /// </summary>
    public class KeywordPlanner : ExampleBase
    {
        public override string Description
        {
            get { return "Keyword Planner | AdInsight V13"; }
        }

        public async override Task RunAsync(AuthorizationData authorizationData)
        {
            try
            {
                ApiEnvironment environment = ((OAuthDesktopMobileAuthCodeGrant)authorizationData.Authentication).Environment;

                AdInsightExampleHelper AdInsightExampleHelper = new AdInsightExampleHelper(
                    OutputStatusMessageDefault: this.OutputStatusMessage);
                AdInsightExampleHelper.AdInsightService = new ServiceClient<IAdInsightService>(
                    authorizationData: authorizationData,
                    environment: environment);

                // Use the GetKeywordIdeaCategories operation to get a list of valid category identifiers.
                // A category identifier will be used in the CategorySearchParameter below.

                OutputStatusMessage("-----\nGetKeywordIdeaCategories:");
                var getKeywordIdeaCategoriesResponse = await AdInsightExampleHelper.GetKeywordIdeaCategoriesAsync();
                var categoryId = (long)(getKeywordIdeaCategoriesResponse?.KeywordIdeaCategories?.ToList()[0].CategoryId);
                OutputStatusMessage(string.Format("CategoryId {0} will be used in the CategorySearchParameter below", categoryId));

                // You must specify the attributes that you want in each returned KeywordIdea.

                var ideaAttributes = new List<KeywordIdeaAttribute>
                {
                    KeywordIdeaAttribute.AdGroupId,
                    KeywordIdeaAttribute.AdGroupName,
                    KeywordIdeaAttribute.AdImpressionShare,
                    KeywordIdeaAttribute.Competition,
                    KeywordIdeaAttribute.Keyword,
                    KeywordIdeaAttribute.MonthlySearchCounts,
                    KeywordIdeaAttribute.Relevance,
                    KeywordIdeaAttribute.Source,
                    KeywordIdeaAttribute.SuggestedBid,
                };

                var endDateTime = DateTime.UtcNow.AddMonths(-2);
                                
                // Only one of each SearchParameter type can be specified per call. 

                var searchParameters = new List<SearchParameter>
                {
                    // Determines the start and end month for MonthlySearchCounts data returned with each KeywordIdea.
                    // The date range search parameter is optional. If you do not include the DateRangeSearchParameter 
                    // in the GetKeywordIdeas request, then you will not be able to confirm whether the first list item 
                    // within MonthlySearchCounts is data for the previous month, or the month prior. If the date range is 
                    // specified and the most recent month's data is not yet available, then GetKeywordIdeas will return an error.

                    new DateRangeSearchParameter
                    {
                        EndDate = new DayMonthAndYear
                        {
                            Day = 30,
                            Month = 9,
                            Year = 2018
                        },
                        StartDate = new DayMonthAndYear
                        {
                            Day = 1,
                            Month = 9,
                            Year = 2018
                        },
                    },
                    
                    // The CategorySearchParameter corresponds to filling in 'Your product category' under
                    // 'Search for new keywords using a phrase, website, or category' in the 
                    // Microsoft Advertising web application's Keyword Planner tool.
                    // One or more CategorySearchParameter, QuerySearchParameter, or UrlSearchParameter is required.

                    new CategorySearchParameter
                    {
                        // Use the GetKeywordIdeaCategories operation to get a list of valid category identifiers.
                        CategoryId = categoryId
                    },

                    // The QuerySearchParameter corresponds to filling in 'Product or service' under
                    // 'Search for new keywords using a phrase, website, or category' in the 
                    // Microsoft Advertising web application's Keyword Planner tool.
                    // One or more CategorySearchParameter, QuerySearchParameter, or UrlSearchParameter is required.
                    // When calling GetKeywordIdeas, if ExpandIdeas = false the QuerySearchParameter is required. 

                    new QuerySearchParameter
                    {
                        Queries = new List<string>
                        {
                            "tennis",
                            "tennis shoes",
                            "running",
                            "running shoes",
                            "cross training",
                            "running",
                        },
                    },

                    // The UrlSearchParameter corresponds to filling in 'Your landing page' under
                    // 'Search for new keywords using a phrase, website, or category' in the 
                    // Microsoft Advertising web application's Keyword Planner tool.
                    // One or more CategorySearchParameter, QuerySearchParameter, or UrlSearchParameter is required.

                    new UrlSearchParameter
                    {
                        Url = "contoso.com"
                    },
                    
                    // The LanguageSearchParameter, LocationSearchParameter, and NetworkSearchParameter
                    // correspond to the 'Keyword Planner' -> 'Search for new keywords using a phrase, website, or category' ->
                    // 'Targeting' workflow in the Microsoft Advertising web application.
                    // Each of these search parameters are required.

                    new LanguageSearchParameter
                    {
                        // You must specify exactly one language

                        Languages = new List<LanguageCriterion>
                        {
                            new LanguageCriterion
                            {
                                Language = "English",
                            },
                        },
                    },
                    new LocationSearchParameter
                    {
                        // You must include at least one location.

                        Locations = new List<LocationCriterion>
                        {
                            new LocationCriterion
                            {
                                // United States
                                LocationId = 190,
                            },
                        }
                    },
                    new NetworkSearchParameter
                    {
                        Network = new NetworkCriterion
                        {
                            Network = NetworkType.OwnedAndOperatedAndSyndicatedSearch,
                        }
                    },

                    // The CompetitionSearchParameter, ExcludeAccountKeywordsSearchParameter, IdeaTextSearchParameter, 
                    // ImpressionShareSearchParameter, SearchVolumeSearchParameter, and SuggestedBidSearchParameter  
                    // correspond to the 'Keyword Planner' -> 'Search for new keywords using a phrase, website, or category' -> 
                    // 'Search options' workflow in the Microsoft Advertising web application.
                    // Use these options to refine what keywords we suggest. You can limit the keywords by historical data, 
                    // hide keywords already in your account, and include or exclude specific keywords.
                    // Each of these search parameters are optional.

                    new CompetitionSearchParameter
                    {
                        CompetitionLevels = new List<CompetitionLevel>
                        {
                            CompetitionLevel.High,
                            CompetitionLevel.Medium,
                            CompetitionLevel.Low
                        }
                    },
                    new ExcludeAccountKeywordsSearchParameter
                    {
                        ExcludeAccountKeywords = false,
                    },
                    new IdeaTextSearchParameter
                    {
                        // The match type is required. Only Broad is supported.

                        Excluded = new List<Keyword>
                        {
                            new Keyword
                            {
                                Text = "tennis court",
                                MatchType = MatchType.Broad
                            },
                            new Keyword
                            {
                                Text = "tennis pro",
                                MatchType = MatchType.Broad
                            }
                        },
                        Included = new List<Keyword>
                        {
                            new Keyword
                            {
                                Text = "athletic clothing",
                                MatchType = MatchType.Broad
                            },
                            new Keyword
                            {
                                Text = "athletic shoes",
                                MatchType = MatchType.Broad
                            }
                        },
                    },
                    new ImpressionShareSearchParameter
                    {
                        // Equivalent of '0 <= value <= 50'
                        Maximum = 50,
                        Minimum = 0,
                    },
                    new SearchVolumeSearchParameter
                    {
                        // Equivalent of 'value >= 50'
                        Maximum = null,
                        Minimum = 50,
                    },
                    new SuggestedBidSearchParameter
                    {
                        // Equivalent of both 'value <= 50' and '0 <= value <= 50'
                        Maximum = 50,
                        Minimum = null,
                    },

                    // Setting the device criterion is not available in the 
                    // 'Keyword Planner' -> 'Search for new keywords using a phrase, website, or category'
                    // workflow in the Microsoft Advertising web application.
                    // The DeviceSearchParameter is optional and by default the keyword ideas data
                    // are aggregated for all devices.

                    new DeviceSearchParameter
                    {
                        Device = new DeviceCriterion
                        {
                            // Possible values are All, Computers, Tablets, Smartphones
                            DeviceName = "All",
                        },
                    },
                };

                // If ExpandIdeas is false, the QuerySearchParameter is required.

                OutputStatusMessage("-----\nGetKeywordIdeas:");
                var getKeywordIdeasResponse = await AdInsightExampleHelper.GetKeywordIdeasAsync(
                    expandIdeas: true,
                    ideaAttributes: ideaAttributes,
                    searchParameters: searchParameters);

                var keywordIdeas = getKeywordIdeasResponse?.KeywordIdeas;
                if(keywordIdeas == null || keywordIdeas.Count < 1)
                {
                    OutputStatusMessage("No keyword ideas are available for the search parameters.");
                    return;
                }
                OutputStatusMessage("KeywordIdeas:");
                AdInsightExampleHelper.OutputArrayOfKeywordIdea(keywordIdeas);

                // Let's get traffic estimates for each returned keyword idea.

                // The returned ad group ID within each keyword idea will either be null or negative.
                // Negative identifiers can be used to map the keyword ideas into suggested new ad groups. 
                // A null ad group identifier indicates that the keyword idea was sourced from your 
                // keyword idea search parameter.

                // In this example we will use the suggested ad groups to request traffic estimates.
                // Each of the seed keyword ideas will be submitted in the same ad group.

                var adGroupIds = keywordIdeas.Select(idea => idea.AdGroupId).Distinct().ToList();
                var adGroupEstimatorCount = adGroupIds.Count;
                var seedOffset = adGroupIds.Contains(null) ? 0 : 1;
                
                var adGroupEstimators = new AdGroupEstimator[adGroupEstimatorCount];
                for(int index = 0; index < adGroupEstimatorCount; index++)
                {
                    adGroupEstimators[index] = new AdGroupEstimator
                    {
                        // The AdGroupId is reserved for future use.
                        // The traffic estimates are not based on any specific ad group. 
                        AdGroupId = null,

                        // We will add new keyword estimators while iterating the keyword ideas below.
                        KeywordEstimators = new List<KeywordEstimator>(),

                        // Optionally you can set an ad group level max CPC (maximum search bid)
                        MaxCpc = 5.00
                    };
                }

                foreach(var keywordIdea in keywordIdeas)
                {
                    var keywordEstimator = new KeywordEstimator
                    {
                        Keyword = new Keyword
                        {
                            // The keyword Id is reserved for future use.
                            // The returned estimates are not based on any specific keyword.
                            Id = null,
                            
                            // The match type is required. Exact, Broad, and Phrase are supported.
                            MatchType = MatchType.Exact,

                            // Use the suggested keyword
                            Text = keywordIdea.Keyword
                        },

                        // Round the suggested bid to two decimal places
                        MaxCpc = keywordIdea.SuggestedBid > 0.04 ? keywordIdea.SuggestedBid : null,
                    };

                    var index = keywordIdea.AdGroupId != null ? -(long)keywordIdea.AdGroupId - seedOffset : 0;

                    adGroupEstimators[index].KeywordEstimators.Add(keywordEstimator);
                }

                // Currently you can include only one CampaignEstimator per service call.

                var campaigns = new List<CampaignEstimator>
                {
                    new CampaignEstimator
                    {
                        // Let's use the ad group and keyword estimators that were sourced from keyword ideas above.

                        AdGroupEstimators = adGroupEstimators,

                        // The CampaignId is reserved for future use.
                        // The returned estimates are not based on any specific campaign.

                        CampaignId = null,

                        DailyBudget = 50.00,

                        NegativeKeywords = new List<NegativeKeyword>
                        {
                            new NegativeKeyword
                            {
                                Text = "foo",
                                MatchType = MatchType.Exact,
                            },
                        },

                        // The location, language, and network criterions are required for traffic estimates.

                        Criteria = new List<Criterion>
                        {
                            // You must include at least one location.

                            new LocationCriterion
                            {
                                // United States
                                LocationId = 190
                            },

                            // You must specify exactly one language criterion

                            new LanguageCriterion
                            {
                                Language = "English"
                            },

                            // You must specify exactly one network criterion

                            new NetworkCriterion
                            {
                                Network = NetworkType.OwnedAndOperatedAndSyndicatedSearch
                            },

                            // Optionally you can specify exactly one device.
                            // If you do not specify a device, the returned traffic estimates 
                            // are aggregated for all devices.
                            // The "All" device name is equivalent to omitting the DeviceCriterion.

                            new DeviceCriterion
                            {
                                DeviceName = "All"
                            },
                        },
                    },
                };

                OutputStatusMessage("-----\nGetKeywordTrafficEstimates:");
                var getKeywordTrafficEstimatesResponse = await AdInsightExampleHelper.GetKeywordTrafficEstimatesAsync(
                    campaignEstimators: campaigns);
                OutputStatusMessage("CampaignEstimates:");
                AdInsightExampleHelper.OutputArrayOfCampaignEstimate(getKeywordTrafficEstimatesResponse?.CampaignEstimates);
            }
            // Catch authentication exceptions
            catch (OAuthTokenRequestException ex)
            {
                OutputStatusMessage(string.Format("Couldn't get OAuth tokens. Error: {0}. Description: {1}", ex.Details.Error, ex.Details.Description));
            }
            // Catch AdInsight service exceptions
            catch (FaultException<AdApiFaultDetail> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.Errors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (FaultException<ApiFaultDetail> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.OperationErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
                OutputStatusMessage(string.Join("; ", ex.Detail.BatchErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (Exception ex)
            {
                OutputStatusMessage(ex.Message);
            }
        }
    }
}
package com.microsoft.bingads.examples.v13;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashSet;

import com.microsoft.bingads.*;
import com.microsoft.bingads.v13.adinsight.*;

public class KeywordPlanner extends ExampleBase {
    
    public static void main(java.lang.String[] args) {
     
        try
        {
            authorizationData = getAuthorizationData(); 
             
            AdInsightExampleHelper.AdInsightService = new ServiceClient<IAdInsightService>(
                    authorizationData, 
                    API_ENVIRONMENT,
                    IAdInsightService.class);
                         
            // Use the GetKeywordIdeaCategories operation to get a list of valid category identifiers.
            // A category identifier will be used in the CategorySearchParameter below.
            
            outputStatusMessage("-----\nGetKeywordIdeaCategories:");
            GetKeywordIdeaCategoriesResponse getKeywordIdeaCategoriesResponse = AdInsightExampleHelper.getKeywordIdeaCategories();
            if(getKeywordIdeaCategoriesResponse == null){
                outputStatusMessage(String.format("This example requires keyword categories."));
                return;
            }
            java.lang.Long categoryId = (long)(getKeywordIdeaCategoriesResponse.getKeywordIdeaCategories().getKeywordIdeaCategories().get(0).getCategoryId());
            outputStatusMessage(String.format("CategoryId %s will be used in the CategorySearchParameter below", categoryId));

            // You must specify the attributes that you want in each returned KeywordIdea.

            ArrayOfKeywordIdeaAttribute ideaAttributes = new ArrayOfKeywordIdeaAttribute();
            ideaAttributes.getKeywordIdeaAttributes().add(KeywordIdeaAttribute.AD_GROUP_ID);
            ideaAttributes.getKeywordIdeaAttributes().add(KeywordIdeaAttribute.AD_GROUP_NAME);
            ideaAttributes.getKeywordIdeaAttributes().add(KeywordIdeaAttribute.AD_IMPRESSION_SHARE);
            ideaAttributes.getKeywordIdeaAttributes().add(KeywordIdeaAttribute.COMPETITION);
            ideaAttributes.getKeywordIdeaAttributes().add(KeywordIdeaAttribute.KEYWORD);
            ideaAttributes.getKeywordIdeaAttributes().add(KeywordIdeaAttribute.MONTHLY_SEARCH_COUNTS);
            ideaAttributes.getKeywordIdeaAttributes().add(KeywordIdeaAttribute.RELEVANCE);
            ideaAttributes.getKeywordIdeaAttributes().add(KeywordIdeaAttribute.SOURCE);
            ideaAttributes.getKeywordIdeaAttributes().add(KeywordIdeaAttribute.SUGGESTED_BID);
                        
            // Only one of each SearchParameter type can be specified per call. 

            ArrayOfSearchParameter searchParameters = new ArrayOfSearchParameter();
            
            // Determines the start and end month for MonthlySearchCounts data returned with each KeywordIdea.
            // The date range search parameter is optional. If you do not include the DateRangeSearchParameter 
            // in the GetKeywordIdeas request, then you will not be able to confirm whether the first list item 
            // within MonthlySearchCounts is data for the previous month, or the month prior. If the date range is 
            // specified and the most recent month's data is not yet available, then GetKeywordIdeas will return an error.

            Calendar calendar = Calendar.getInstance();
            DateRangeSearchParameter dateRangeSearchParameter = new DateRangeSearchParameter();
            DayMonthAndYear endDate = new DayMonthAndYear();
            endDate.setDay(30);
            endDate.setMonth(9);
            endDate.setYear(2018);
            DayMonthAndYear startDate = new DayMonthAndYear();
            startDate.setDay(1);
            startDate.setMonth(9);
            startDate.setYear(2018);
            dateRangeSearchParameter.setEndDate(endDate);
            dateRangeSearchParameter.setStartDate(startDate);            
            searchParameters.getSearchParameters().add(dateRangeSearchParameter);

            // The CategorySearchParameter corresponds to filling in 'Your product category' under
            // 'Search for new keywords using a phrase, website, or category' in the 
            // Bing Ads web application's Keyword Planner tool.
            // One or more CategorySearchParameter, QuerySearchParameter, or UrlSearchParameter is required.

            CategorySearchParameter categorySearchParameter = new CategorySearchParameter();
            // Use the GetKeywordIdeaCategories operation (e.g., above) to get a list of valid category identifiers.
            categorySearchParameter.setCategoryId(categoryId);            
            searchParameters.getSearchParameters().add(categorySearchParameter);

            // The QuerySearchParameter corresponds to filling in 'Product or service' under
            // 'Search for new keywords using a phrase, website, or category' in the 
            // Bing Ads web application's Keyword Planner tool.
            // One or more CategorySearchParameter, QuerySearchParameter, or UrlSearchParameter is required.
            // When calling GetKeywordIdeas, if ExpandIdeas = false the QuerySearchParameter is required. 

            QuerySearchParameter querySearchParameter = new QuerySearchParameter();
            ArrayOfstring queries = new ArrayOfstring();
            queries.getStrings().add("tennis");
            queries.getStrings().add("tennis shoes");
            queries.getStrings().add("running");
            queries.getStrings().add("running shoes");
            queries.getStrings().add("cross training");          
            querySearchParameter.setQueries(queries);            
            searchParameters.getSearchParameters().add(querySearchParameter);
            
            // The UrlSearchParameter corresponds to filling in 'Your landing page' under
            // 'Search for new keywords using a phrase, website, or category' in the 
            // Bing Ads web application's Keyword Planner tool.
            // One or more CategorySearchParameter, QuerySearchParameter, or UrlSearchParameter is required.

            UrlSearchParameter urlSearchParameter = new UrlSearchParameter();
            urlSearchParameter.setUrl("contoso.com");            
            searchParameters.getSearchParameters().add(urlSearchParameter);
            
            // The LanguageSearchParameter, LocationSearchParameter, and NetworkSearchParameter
            // correspond to the 'Keyword Planner' -> 'Search for new keywords using a phrase, website, or category' ->
            // 'Targeting' workflow in the Bing Ads web application.
            // Each of these search parameters are required.

            LanguageSearchParameter languageSearchParameter = new LanguageSearchParameter();
            ArrayOfLanguageCriterion languages = new ArrayOfLanguageCriterion();
            LanguageCriterion englishLanguage =  new LanguageCriterion();
            englishLanguage.setLanguage("English");  
            // You must specify exactly one language
            languages.getLanguageCriterions().add(englishLanguage);
            languageSearchParameter.setLanguages(languages);               
            searchParameters.getSearchParameters().add(languageSearchParameter);
                    
            LocationSearchParameter locationSearchParameter = new LocationSearchParameter();
            ArrayOfLocationCriterion locations = new ArrayOfLocationCriterion();
            LocationCriterion unitedStatesLocationCriterion = new LocationCriterion();
            // United States
            unitedStatesLocationCriterion.setLocationId(190L);
            // You must specify between 1 and 100 locations
            locations.getLocationCriterions().add(unitedStatesLocationCriterion);
            locationSearchParameter.setLocations(locations);                   
            searchParameters.getSearchParameters().add(locationSearchParameter);
                    
            NetworkSearchParameter networkSearchParameter = new NetworkSearchParameter();
            NetworkCriterion networkCriterion = new NetworkCriterion();
            networkCriterion.setNetwork(NetworkType.OWNED_AND_OPERATED_AND_SYNDICATED_SEARCH);
            networkSearchParameter.setNetwork(networkCriterion);            
            searchParameters.getSearchParameters().add(networkSearchParameter);
            
            // The CompetitionSearchParameter, ExcludeAccountKeywordsSearchParameter, IdeaTextSearchParameter, 
            // ImpressionShareSearchParameter, SearchVolumeSearchParameter, and SuggestedBidSearchParameter  
            // correspond to the 'Keyword Planner' -> 'Search for new keywords using a phrase, website, or category' -> 
            // 'Search options' workflow in the Bing Ads web application.
            // Use these options to refine what keywords we suggest. You can limit the keywords by historical data, 
            // hide keywords already in your account, and include or exclude specific keywords.
            // Each of these search parameters are optional.

            CompetitionSearchParameter competitionSearchParameter = new CompetitionSearchParameter();
            ArrayOfCompetitionLevel competitionLevels = new ArrayOfCompetitionLevel();
            competitionLevels.getCompetitionLevels().add(CompetitionLevel.LOW);
            competitionLevels.getCompetitionLevels().add(CompetitionLevel.MEDIUM);
            competitionLevels.getCompetitionLevels().add(CompetitionLevel.HIGH);
            competitionSearchParameter.setCompetitionLevels(competitionLevels);            
            searchParameters.getSearchParameters().add(competitionSearchParameter);
            
            ExcludeAccountKeywordsSearchParameter excludeAccountKeywordsSearchParameter = new ExcludeAccountKeywordsSearchParameter();
            excludeAccountKeywordsSearchParameter.setExcludeAccountKeywords(false);
            searchParameters.getSearchParameters().add(excludeAccountKeywordsSearchParameter);
            
            
            IdeaTextSearchParameter ideaTextSearchParameter = new IdeaTextSearchParameter();
            // The match type is required. Only Broad is supported.
            ArrayOfKeyword excludedKeywords = new ArrayOfKeyword();
            Keyword excludedKeyword1 = new Keyword();
            excludedKeyword1.setText("tennis court");
            excludedKeyword1.setMatchType(MatchType.BROAD);
            excludedKeywords.getKeywords().add(excludedKeyword1);
            Keyword excludedKeyword2 = new Keyword();
            excludedKeyword2.setText("tennis pro");
            excludedKeyword2.setMatchType(MatchType.BROAD);
            excludedKeywords.getKeywords().add(excludedKeyword2);
            ArrayOfKeyword includedKeywords = new ArrayOfKeyword();
            Keyword includedKeyword1 = new Keyword();
            includedKeyword1.setText("athletic clothing");
            includedKeyword1.setMatchType(MatchType.BROAD);
            includedKeywords.getKeywords().add(includedKeyword1);
            Keyword includedKeyword2 = new Keyword();
            includedKeyword2.setText("athletic shoes");
            includedKeyword2.setMatchType(MatchType.BROAD);
            includedKeywords.getKeywords().add(includedKeyword2);
            ideaTextSearchParameter.setExcluded(excludedKeywords);
            ideaTextSearchParameter.setIncluded(includedKeywords);
            searchParameters.getSearchParameters().add(ideaTextSearchParameter);
            
            // Equivalent of '0 <= value <= 50'
            ImpressionShareSearchParameter impressionShareSearchParameter = new ImpressionShareSearchParameter();
            impressionShareSearchParameter.setMaximum(50D);
            impressionShareSearchParameter.setMinimum(0D);
            searchParameters.getSearchParameters().add(impressionShareSearchParameter);
            
            // Equivalent of 'value >= 50'
            SearchVolumeSearchParameter searchVolumeSearchParameter = new SearchVolumeSearchParameter();
            searchVolumeSearchParameter.setMaximum(null);
            searchVolumeSearchParameter.setMinimum(50L);
            searchParameters.getSearchParameters().add(searchVolumeSearchParameter);
                        
            // Equivalent of both 'value <= 50' and '0 <= value <= 50'
            SuggestedBidSearchParameter suggestedBidSearchParameter = new SuggestedBidSearchParameter();
            suggestedBidSearchParameter.setMaximum(50D);
            suggestedBidSearchParameter.setMinimum(null);
            searchParameters.getSearchParameters().add(suggestedBidSearchParameter);

            // Setting the device criterion is not available in the 
            // 'Keyword Planner' -> 'Search for new keywords using a phrase, website, or category'
            // workflow in the Bing Ads web application.
            // The DeviceSearchParameter is optional and by default the keyword ideas data
            // are aggregated for all devices.
            
            DeviceSearchParameter deviceSearchParameter = new DeviceSearchParameter();
            DeviceCriterion deviceCriterion = new DeviceCriterion();
            // Possible values are All, Computers, Tablets, Smartphones
            deviceCriterion.setDeviceName("All");
            deviceSearchParameter.setDevice(deviceCriterion);
            searchParameters.getSearchParameters().add(deviceSearchParameter);

            // If ExpandIdeas is false, the QuerySearchParameter is required.

            outputStatusMessage("-----\nGetKeywordIdeas:");
            GetKeywordIdeasResponse getKeywordIdeasResponse = AdInsightExampleHelper.getKeywordIdeas(
                true,
                ideaAttributes,
                searchParameters);

            ArrayOfKeywordIdea keywordIdeas = getKeywordIdeasResponse.getKeywordIdeas();
            if(keywordIdeas == null || keywordIdeas.getKeywordIdeas().size() < 1)
            {
                outputStatusMessage("No keyword ideas are available for the search parameters.");
                return;
            }
            outputStatusMessage("KeywordIdeas:");
            AdInsightExampleHelper.outputArrayOfKeywordIdea(keywordIdeas);

            // Let's get traffic estimates for each returned keyword idea.

            // The returned ad group ID within each keyword idea will either be null or negative.
            // Negative identifiers can be used to map the keyword ideas into suggested new ad groups. 
            // A null ad group identifier indicates that the keyword idea was sourced from your 
            // keyword idea search parameter.

            // In this example we will use the suggested ad groups to request traffic estimates.
            // Each of the seed keyword ideas will be submitted in the same ad group.

            ArrayOflong keywordIdeaAdGroupIds = new ArrayOflong();
            for(KeywordIdea keywordIdea : keywordIdeas.getKeywordIdeas()){
                keywordIdeaAdGroupIds.getLongs().add(keywordIdea.getAdGroupId());
            }
            ArrayList<java.lang.Long> adGroupIds = new ArrayList<java.lang.Long>(new HashSet<Long>(keywordIdeaAdGroupIds.getLongs()));
            
            int adGroupEstimatorCount = adGroupIds.size();
            int seedOffset = adGroupIds.contains(null) ? 0 : 1;

            AdGroupEstimator[] adGroupEstimators = new AdGroupEstimator[adGroupEstimatorCount];
            for(int index = 0; index < adGroupEstimatorCount; index++)
            {
                adGroupEstimators[index] = new AdGroupEstimator();
                
                // The AdGroupId is reserved for future use.
                // The traffic estimates are not based on any specific ad group. 
                adGroupEstimators[index].setAdGroupId(null);
                
                // Optionally you can set an ad group level max CPC (maximum search bid)
                adGroupEstimators[index].setMaxCpc(5.00D);
                
                // We will add new keyword estimators while iterating the keyword ideas below.
                ArrayOfKeywordEstimator keywordEstimators = new ArrayOfKeywordEstimator();
                adGroupEstimators[index].setKeywordEstimators(keywordEstimators);
            }

            for(KeywordIdea keywordIdea : keywordIdeas.getKeywordIdeas())
            {
                KeywordEstimator keywordEstimator = new KeywordEstimator();
                Keyword keyword = new Keyword();
                // The keyword Id is reserved for future use.
                // The returned estimates are not based on any specific keyword.
                keyword.setId(null);
                // The match type is required. Exact, Broad, and Phrase are supported.
                keyword.setMatchType(MatchType.EXACT);
                // Use the suggested keyword
                keyword.setText(keywordIdea.getKeyword());
                keywordEstimator.setKeyword(keyword);
                double maxCpc = keywordIdea.getSuggestedBid() > 0.04 ? 
                        keywordIdea.getSuggestedBid() : null;
                keywordEstimator.setMaxCpc(maxCpc);
                
                long index = keywordIdea.getAdGroupId() != null ? -(long)keywordIdea.getAdGroupId() - seedOffset : 0;

                adGroupEstimators[(int)index].getKeywordEstimators().getKeywordEstimators().add(keywordEstimator);
            }

            // Currently you can include only one CampaignEstimator per service call.

            ArrayOfCampaignEstimator campaigns = new ArrayOfCampaignEstimator();
            CampaignEstimator campaignEstimator = new CampaignEstimator();
                        
            // Let's use the ad group and keyword estimators that were sourced from keyword ideas above.
            ArrayOfAdGroupEstimator adGroups = new ArrayOfAdGroupEstimator();
            for(int index = 0; index < adGroupEstimatorCount; index++)
            {
                adGroups.getAdGroupEstimators().add(adGroupEstimators[index]);
            }
            campaignEstimator.setAdGroupEstimators(adGroups);
           
            // The CampaignId is reserved for future use.
            // The returned estimates are not based on any specific campaign.
            campaignEstimator.setCampaignId(null);

            campaignEstimator.setDailyBudget(50.00D);

            ArrayOfNegativeKeyword negativeKeywords = new ArrayOfNegativeKeyword();
            NegativeKeyword negativeKeyword = new NegativeKeyword();
            negativeKeyword.setText("foo");
            negativeKeyword.setMatchType(MatchType.EXACT);
            negativeKeywords.getNegativeKeywords().add(negativeKeyword);            
            campaignEstimator.setNegativeKeywords(negativeKeywords);

            // The location, language, and network criterions are required for traffic estimates.

            ArrayOfCriterion trafficEstimateCriteria = new ArrayOfCriterion();
            // You must specify between 1 and 100 locations
            trafficEstimateCriteria.getCriterions().add(unitedStatesLocationCriterion);
            // You must specify exactly one language criterion
            trafficEstimateCriteria.getCriterions().add(englishLanguage);
            // You must specify exactly one network criterion
            trafficEstimateCriteria.getCriterions().add(networkCriterion);
            // Optionally you can specify exactly one device.
            // If you do not specify a device, the returned traffic estimates 
            // are aggregated for all devices.
            // The "All" device name is equivalent to omitting the DeviceCriterion.
            trafficEstimateCriteria.getCriterions().add(deviceCriterion);
            campaignEstimator.setCriteria(trafficEstimateCriteria);
            
            campaigns.getCampaignEstimators().add(campaignEstimator);
            
            outputStatusMessage("-----\nGetKeywordTrafficEstimates:");
            GetKeywordTrafficEstimatesResponse getKeywordTrafficEstimatesResponse = AdInsightExampleHelper.getKeywordTrafficEstimates(
                    campaigns);
            outputStatusMessage("CampaignEstimates:");
            AdInsightExampleHelper.outputArrayOfCampaignEstimate(getKeywordTrafficEstimatesResponse.getCampaignEstimates());        
        } 
        catch (Exception ex) {
            String faultXml = ExampleExceptionHelper.getBingAdsExceptionFaultXml(ex, System.out);
            outputStatusMessage(faultXml);
            String message = ExampleExceptionHelper.handleBingAdsSDKException(ex, System.out);
            outputStatusMessage(message);
        }
    }
}
<?php

use Microsoft\MsAds\Rest\ApiException;
use Microsoft\MsAds\Rest\Model\AdInsightService\AdGroupEstimator;
use Microsoft\MsAds\Rest\Model\AdInsightService\CampaignEstimator;
use Microsoft\MsAds\Rest\Model\AdInsightService\DateRangeSearchParameter;
use Microsoft\MsAds\Rest\Model\AdInsightService\DayMonthAndYear;
use Microsoft\MsAds\Rest\Model\AdInsightService\GetKeywordIdeasRequest;
use Microsoft\MsAds\Rest\Model\AdInsightService\GetKeywordTrafficEstimatesRequest;
use Microsoft\MsAds\Rest\Model\AdInsightService\Keyword;
use Microsoft\MsAds\Rest\Model\AdInsightService\KeywordEstimator;
use Microsoft\MsAds\Rest\Model\AdInsightService\KeywordIdea;
use Microsoft\MsAds\Rest\Model\AdInsightService\KeywordIdeaAttribute;
use Microsoft\MsAds\Rest\Model\AdInsightService\LanguageCriterion;
use Microsoft\MsAds\Rest\Model\AdInsightService\LanguageSearchParameter;
use Microsoft\MsAds\Rest\Model\AdInsightService\LocationCriterion;
use Microsoft\MsAds\Rest\Model\AdInsightService\LocationSearchParameter;
use Microsoft\MsAds\Rest\Model\AdInsightService\MatchType;
use Microsoft\MsAds\Rest\Model\AdInsightService\NegativeKeyword;
use Microsoft\MsAds\Rest\Model\AdInsightService\NetworkCriterion;
use Microsoft\MsAds\Rest\Model\AdInsightService\NetworkSearchParameter;
use Microsoft\MsAds\Rest\Model\AdInsightService\NetworkType;
use Microsoft\MsAds\Rest\Model\AdInsightService\QuerySearchParameter;
use Microsoft\MsAds\Rest\Test\RestApiTestBase;

class KeywordPlannerTest extends RestApiTestBase
{
    /**
     * @throws ApiException
     */
    public function testGetKeywordIdeas()
    {
        $ideaAttributes = [
            KeywordIdeaAttribute::AD_GROUP_ID,
            KeywordIdeaAttribute::AD_GROUP_NAME,
            KeywordIdeaAttribute::KEYWORD,
            KeywordIdeaAttribute::SOURCE,
            KeywordIdeaAttribute::MONTHLY_SEARCH_COUNTS,
            KeywordIdeaAttribute::SUGGESTED_BID,
            KeywordIdeaAttribute::COMPETITION,
            KeywordIdeaAttribute::RELEVANCE,
            KeywordIdeaAttribute::AD_IMPRESSION_SHARE
        ];
        $searchParameters = [];
        $searchParameters[] = new DateRangeSearchParameter([
            'StartDate' => new DayMonthAndYear([
                'Day' => 1,
                'Month' => 1,
                'Year' => date('Y')
            ]),
            'EndDate' => new DayMonthAndYear([
                'Day' => 1,
                'Month' => date('m') - 1,
                'Year' => date('Y')
            ])
        ]);
        $searchParameters[] = new QuerySearchParameter(
            [
                'Queries' => ["tennis", "tennis shoes", "running", "running shoes", "cross training", "running"]
            ]
        );
        $searchParameters[] = new LanguageSearchParameter([
            'Languages' => [new LanguageCriterion([
                'Language' => 'English',
                ]
            )]
        ]);
        $searchParameters[] = new LocationSearchParameter([
            'Locations' => [new LocationCriterion(
                [
                    'LocationId' => 190 // United States
                ]
            )]
        ]);
        $searchParameters[] = new NetworkSearchParameter([
            'Network' => new NetworkCriterion([
                'Network' => NetworkType::OWNED_AND_OPERATED_AND_SYNDICATED_SEARCH
            ])
        ]);
        $request = new GetKeywordIdeasRequest([
            'ExpandIdeas' => true,
            'IdeaAttributes' => $ideaAttributes,
            'SearchParameters' => $searchParameters
        ]);
        $response = self::$adInsightServiceApi->getKeywordIdeas($request);
        $ideas = $response->getKeywordIdeas();
        $this->assertNotEmpty($ideas);
        $this->assertGreaterThan(0, count($ideas));
        return $ideas;
    }

    /**
     * @depends testGetKeywordIdeas
     * @throws ApiException
     */
    public function testGetKeywordTrafficEstimates(array $ideas)
    {
        // Build ad group estimators from keyword ideas
        $ideaAdGroupIds = array();
        foreach ($ideas as $keywordIdea)
        {
            if (!$keywordIdea instanceof KeywordIdea) {
                continue;
            }
            $ideaAdGroupIds[] = $keywordIdea->getAdGroupId();
        }
        $adGroupIds = array_unique($ideaAdGroupIds, SORT_REGULAR);
        $adGroupEstimatorCount = count($adGroupIds);
        $seedOffset = in_array(null, $adGroupIds) ? 0 : 1;
        $adGroupEstimators = [];

        for($index = 0; $index < $adGroupEstimatorCount; $index++)
        {
            $adGroupEstimators[]  = new AdGroupEstimator([
                'KeywordEstimators' => [],
                'MaxCpc' => 5.00
            ]);
        }

        foreach ($ideas as $keywordIdea) {
            if (!$keywordIdea instanceof KeywordIdea) {
                continue;
            }
            $index = ($keywordIdea->getAdGroupId() != null) ? -($keywordIdea->getAdGroupId()) - $seedOffset : 0;
            $adGroupEstimators[$index]->setKeywordEstimators(
                array_merge(
                    $adGroupEstimators[$index]->getKeywordEstimators(),
                    [
                        new KeywordEstimator([
                            'Keyword' => new Keyword([
                                'Text' => $keywordIdea->getKeyword(),
                                'MatchType' => MatchType::EXACT
                            ]),
                            'MaxCpc' =>  $keywordIdea->getSuggestedBid() > 0.04 ? $keywordIdea->getSuggestedBid() : null
                        ])
                    ]
                )
            );
        }

        // Build campaign estimator
        $campaignEstimator = new CampaignEstimator([
            'AdGroupEstimators' => $adGroupEstimators,
            'DailyBudget' => 50.00,
            'NegativeKeywords' => [
                new NegativeKeyword([
                    'Text' => 'foo',
                    'MatchType' => MatchType::EXACT
                ])
            ],
            'Criteria' => [
                new LanguageCriterion([
                    'Language' => 'English'
                ]),
                new NetworkCriterion(
                    [
                        'Network' => NetworkType::OWNED_AND_OPERATED_AND_SYNDICATED_SEARCH
                    ]
                ),
                new LocationCriterion([
                    'LocationId' => 190, // United States
                ])
            ]
        ]);

        $request = new GetKeywordTrafficEstimatesRequest([
            'CampaignEstimators' => [$campaignEstimator]
        ]);
        $response = self::$adInsightServiceApi->getKeywordTrafficEstimates($request);
        $this->assertNotEmpty($response->getCampaignEstimates());
        $campaignEstimates = $response->getCampaignEstimates();
        print("Campaign Estimates:\n");
        print_r($campaignEstimates);
    }
}

from datetime import datetime
from auth_helper import *
from openapi_client.models.adinsight import *


def main():
    try:
        # Test 1: Get Keyword Ideas
        print("=" * 60)
        print("Test 1: Getting Keyword Ideas...")
        print("=" * 60)
        
        # Define attributes we want to retrieve for each keyword idea
        idea_attributes = [
            KeywordIdeaAttribute.ADGROUPID,
            KeywordIdeaAttribute.ADGROUPNAME,
            KeywordIdeaAttribute.KEYWORD,
            KeywordIdeaAttribute.SOURCE,
            KeywordIdeaAttribute.MONTHLYSEARCHCOUNTS,
            KeywordIdeaAttribute.SUGGESTEDBID,
            KeywordIdeaAttribute.COMPETITION,
            KeywordIdeaAttribute.RELEVANCE,
            KeywordIdeaAttribute.ADIMPRESSIONSHARE
        ]
        
        # Set up search parameters
        search_parameters = []
        
        # Date range parameter
        current_date = datetime.now()
        start_date = DayMonthAndYear(
            day=1,
            month=1,
            year=current_date.year - 1
        )
        end_date = DayMonthAndYear(
            day=1,
            month=current_date.month - 1 if current_date.month > 1 else 12,
            year=current_date.year - 1
        )
        
        date_range_param = DateRangeSearchParameter(
            start_date=start_date,
            end_date=end_date
        )
        search_parameters.append(date_range_param)
        
        # Query search parameter
        query_param = QuerySearchParameter(
            queries=["tennis", "tennis shoes", "running", "running shoes", "cross training", "running"]
        )
        search_parameters.append(query_param)
        
        # Language parameter
        language_criterion = LanguageCriterion(
            language="English"
        )
        language_param = LanguageSearchParameter(
            languages=[language_criterion]
        )
        search_parameters.append(language_param)
        
        # Location parameter (United States)
        location_criterion = LocationCriterion(
            location_id='190'
        )
        location_param = LocationSearchParameter(
            locations=[location_criterion]
        )
        search_parameters.append(location_param)
        
        # Network parameter
        network_criterion = NetworkCriterion(
            network=NetworkType.OWNEDANDOPERATEDANDSYNDICATEDSEARCH
        )
        network_param = NetworkSearchParameter(
            network=network_criterion
        )
        search_parameters.append(network_param)
        
        # Create the request
        get_keyword_ideas_request = GetKeywordIdeasRequest(
            expand_ideas=True,
            idea_attributes=idea_attributes,
            search_parameters=search_parameters
        )
        
        # Call the service
        keyword_ideas_response = ad_insight_service.get_keyword_ideas(
            get_keyword_ideas_request=get_keyword_ideas_request
        )
        
        keyword_ideas = keyword_ideas_response.KeywordIdeas
        
        if not keyword_ideas or len(keyword_ideas) == 0:
            print("No keyword ideas found.")
            return
        
        print(f"\nFound {len(keyword_ideas)} keyword ideas:")
        
        # Display first few keyword ideas
        for i, idea in enumerate(keyword_ideas[:10]):  # Show first 10
            print(f"\n  Keyword Idea {i+1}:")
            if hasattr(idea, 'Keyword'):
                print(f"    Keyword: {idea.Keyword}")
            if hasattr(idea, 'Source'):
                print(f"    Source: {idea.Source}")
            if hasattr(idea, 'AdGroupId'):
                print(f"    AdGroupId: {idea.AdGroupId}")
            if hasattr(idea, 'AdGroupName'):
                print(f"    AdGroupName: {idea.AdGroupName}")
            if hasattr(idea, 'SuggestedBid'):
                print(f"    SuggestedBid: {idea.SuggestedBid}")
            if hasattr(idea, 'Competition'):
                print(f"    Competition: {idea.Competition}")
            if hasattr(idea, 'Relevance'):
                print(f"    Relevance: {idea.Relevance}")
            if hasattr(idea, 'MonthlySearchCounts'):
                print(f"    MonthlySearchCounts: {idea.MonthlySearchCounts}")
        
        if len(keyword_ideas) > 10:
            print(f"\n  ... and {len(keyword_ideas) - 10} more keyword ideas")
        
        # Test 2: Get Keyword Traffic Estimates
        print("\n" + "=" * 60)
        print("Test 2: Getting Keyword Traffic Estimates...")
        print("=" * 60)
        
        # Build ad group estimators from keyword ideas
        idea_ad_group_ids = []
        for keyword_idea in keyword_ideas:
            if hasattr(keyword_idea, 'AdGroupId') and keyword_idea.AdGroupId:
                idea_ad_group_ids.append(keyword_idea.AdGroupId)
        
        # Get unique ad group IDs
        unique_ad_group_ids = list(set(idea_ad_group_ids))
        ad_group_estimator_count = len(unique_ad_group_ids)
        seed_offset = 0 if None in unique_ad_group_ids else 1
        
        print(f"\nBuilding {ad_group_estimator_count} ad group estimators...")
        
        # Initialize ad group estimators
        ad_group_estimators = []
        for index in range(ad_group_estimator_count):
            ad_group_estimator = AdGroupEstimator(
                keyword_estimators=[],
                max_cpc=5.00
            )
            ad_group_estimators.append(ad_group_estimator)
        
        # Populate keyword estimators for each ad group
        for keyword_idea in keyword_ideas:
            if not hasattr(keyword_idea, 'Keyword'):
                continue
                
            ad_group_id = keyword_idea.AdGroupId if hasattr(keyword_idea, 'AdGroupId') else None
            
            # Determine the index for this keyword's ad group
            if ad_group_id is not None:
                try:
                    index = unique_ad_group_ids.index(ad_group_id)
                except ValueError:
                    index = 0
            else:
                index = 0
            
            # Create keyword estimator
            suggested_bid = keyword_idea.SuggestedBid if hasattr(keyword_idea, 'SuggestedBid') and keyword_idea.SuggestedBid else None
            max_cpc = suggested_bid if suggested_bid and suggested_bid > 0.04 else None
            
            keyword = Keyword(
                text=keyword_idea.Keyword,
                match_type=MatchType.EXACT
            )
            
            keyword_estimator = KeywordEstimator(
                keyword=keyword,
                max_cpc=max_cpc
            )
            
            # Add to the appropriate ad group estimator
            ad_group_estimators[index].keyword_estimators.append(keyword_estimator)
        
        # Build campaign estimator
        negative_keyword = NegativeKeyword(
            text="foo",
            match_type=MatchType.EXACT
        )
        
        language_criterion = LanguageCriterion(
            language="English"
        )
        
        network_criterion = NetworkCriterion(
            network=NetworkType.OWNEDANDOPERATEDANDSYNDICATEDSEARCH
        )
        
        location_criterion = LocationCriterion(
            location_id='190'  # United States
        )
        
        campaign_estimator = CampaignEstimator(
            ad_group_estimators=ad_group_estimators,
            daily_budget=50.00,
            negative_keywords=[negative_keyword],
            criteria=[language_criterion, network_criterion, location_criterion]
        )
        
        # Create the request
        get_keyword_traffic_estimates_request = GetKeywordTrafficEstimatesRequest(
            campaign_estimators=[campaign_estimator]
        )
        
        # Call the service
        print("\nRequesting keyword traffic estimates...")
        traffic_estimates_response = ad_insight_service.get_keyword_traffic_estimates(
            get_keyword_traffic_estimates_request=get_keyword_traffic_estimates_request
        )
        
        campaign_estimates = traffic_estimates_response.CampaignEstimates
        
        if not campaign_estimates or len(campaign_estimates) == 0:
            print("No campaign estimates found.")
            return
        
        print(f"\nFound {len(campaign_estimates)} campaign estimate(s):")
        
        # Display campaign estimates
        for i, campaign_estimate in enumerate(campaign_estimates):
            print(f"\n  Campaign Estimate {i+1}:")
            
            if hasattr(campaign_estimate, 'AdGroupEstimates') and campaign_estimate.AdGroupEstimates:
                print(f"    Number of Ad Group Estimates: {len(campaign_estimate.AdGroupEstimates)}")
                
                # Show first few ad group estimates
                for j, ad_group_estimate in enumerate(campaign_estimate.AdGroupEstimates[:3]):
                    print(f"\n    Ad Group Estimate {j+1}:")
                    
                    if hasattr(ad_group_estimate, 'KeywordEstimates') and ad_group_estimate.KeywordEstimates:
                        print(f"      Number of Keyword Estimates: {len(ad_group_estimate.KeywordEstimates)}")
                        
                        # Show first few keyword estimates
                        for k, keyword_estimate in enumerate(ad_group_estimate.KeywordEstimates[:5]):
                            if hasattr(keyword_estimate, 'Keyword') and keyword_estimate.Keyword:
                                keyword_text = keyword_estimate.Keyword.Text if hasattr(keyword_estimate.Keyword, 'Text') else 'N/A'
                                print(f"        Keyword {k+1}: {keyword_text}")
                            
                            if hasattr(keyword_estimate, 'Minimum') and keyword_estimate.Minimum:
                                print(f"          Minimum Estimates:")
                                if hasattr(keyword_estimate.Minimum, 'AverageCpc'):
                                    print(f"            Average CPC: {keyword_estimate.Minimum.AverageCpc}")
                                if hasattr(keyword_estimate.Minimum, 'Clicks'):
                                    print(f"            Clicks: {keyword_estimate.Minimum.Clicks}")
                                if hasattr(keyword_estimate.Minimum, 'Impressions'):
                                    print(f"            Impressions: {keyword_estimate.Minimum.Impressions}")
                            
                            if hasattr(keyword_estimate, 'Maximum') and keyword_estimate.Maximum:
                                print(f"          Maximum Estimates:")
                                if hasattr(keyword_estimate.Maximum, 'AverageCpc'):
                                    print(f"            Average CPC: {keyword_estimate.Maximum.AverageCpc}")
                                if hasattr(keyword_estimate.Maximum, 'Clicks'):
                                    print(f"            Clicks: {keyword_estimate.Maximum.Clicks}")
                                if hasattr(keyword_estimate.Maximum, 'Impressions'):
                                    print(f"            Impressions: {keyword_estimate.Maximum.Impressions}")
                        
                        if len(ad_group_estimate.KeywordEstimates) > 5:
                            print(f"        ... and {len(ad_group_estimate.KeywordEstimates) - 5} more keyword estimates")
                
                if len(campaign_estimate.AdGroupEstimates) > 3:
                    print(f"\n    ... and {len(campaign_estimate.AdGroupEstimates) - 3} more ad group estimates")
        
        print("\n" + "=" * 60)
        print("Keyword planner test completed successfully!")
        print("=" * 60)
        
    except Exception as ex:
        print(f"Error occurred: {str(ex)}")
        import traceback
        traceback.print_exc()


if __name__ == '__main__':
    print("Loading the web service client...")
    
    authorization_data = AuthorizationData(
        account_id=None,
        customer_id=None,
        developer_token=DEVELOPER_TOKEN,
        authentication=None,
    )
    
    authenticate(authorization_data)
    
    ad_insight_service = ServiceClient(
        service='AdInsightService',
        version=13,
        authorization_data=authorization_data,
        environment=ENVIRONMENT,
    )
    
    main()

Siehe auch

Erste Schritte mit der Bing Ads-API