Google Ads API is returning to beta status. Please read our blog post for more details.

地理位置定位

本指南对地理位置定位进行了说明,并介绍了如何使用 Google Ads API 为您的广告系列添加、获取及更新地理位置定位。

为什么地理位置定位如此重要?

借助地理位置定位,您可以向特定地理区域的用户投放您的广告。例如,假设您要为某个连锁超市投放广告。如果不使用地理位置定位,您的广告就会在全球所有区域展示,而其中一些区域并未开设该连锁超市,那里的用户可能也会点击您的广告。这除了浪费您的预算之外,还不会带来任何投资回报。但采用了地理位置定位后,您的广告系列就只会在开设了该连锁超市的区域展示广告。此外,这种方法还能让您直接定位搜索本地超市的客户。

通过 Google Ads API,您可以根据国家/地区、区域或特定地理位置点的邻近区域来定位您的广告

详细了解如何将广告定位到地理位置

通过地理位置将广告系列定位到区域

您可以将广告系列定位到 Google Ads 支持进行地理位置定位的任何地理区域,例如国家/地区、州或省、城市或邮政区域。每个可定位的地理位置都会有一个条件 ID 进行唯一地标识。您可以使用 GeoTargetConstantService.SuggestGeoTargetConstants 查找条件 ID。每个 GeoTargetConstantresource_name 格式为 geoTargetConstants/{Criterion ID}。例如,纽约州的 resource_name 值为 geoTargetConstants/21167

您可以使用 CampaignCriterionService 为您的广告系列添加地理位置定位。以下代码段展示了如何使用条件 ID 对广告系列进行定位。

Java

private static CampaignCriterion buildLocationIdCriterion(
    long locationId, String campaignResourceName) {
  Builder criterionBuilder =
      CampaignCriterion.newBuilder().setCampaign(StringValue.of(campaignResourceName));

  criterionBuilder
      .getLocationBuilder()
      .setGeoTargetConstant(
          StringValue.of(GeoTargetConstantName.format(String.valueOf(locationId))));

  return criterionBuilder.build();
}

C#

private CampaignCriterion buildLocationCriterion(long locationId,
    string campaignResourceName)
{
    GeoTargetConstantName location = new GeoTargetConstantName(locationId.ToString());
    return new CampaignCriterion()
    {
        Campaign = campaignResourceName,
        Location = new LocationInfo()
        {
            GeoTargetConstant = location.ToString()
        }
    };
}

PHP

private static function createLocationCampaignCriterionOperation(
    $locationId,
    $campaignResourceName
) {
    // Constructs a campaign criterion for the specified campaign ID using the specified
    // location ID.
    $campaignCriterion = new CampaignCriterion([
        // Creates a location using the specified location ID.
        'location' => new LocationInfo([
            'geo_target_constant' => new StringValue(
                // Besides using location ID, you can also search by location names using
                // GeoTargetConstantServiceClient::suggestGeoTargetConstants() and directly
                // apply GeoTargetConstant::$resourceName here. An example can be found
                // in GetGeoTargetConstantByNames.php.
                ['value' => ResourceNames::forGeoTargetConstant($locationId)]
            )
        ]),
        'campaign' => new StringValue(['value' => $campaignResourceName])
    ]);

    return new CampaignCriterionOperation(['create' => $campaignCriterion]);
}

Python

def create_location_op(client, customer_id, campaign_id, location_id):
    campaign_service = client.get_service('CampaignService', version='v1')
    geo_target_constant_service = client.get_service('GeoTargetConstantService',
                                                     version='v1')

    # Create the campaign criterion.
    campaign_criterion_operation = client.get_type('CampaignCriterionOperation',
                                                   version='v1')
    campaign_criterion = campaign_criterion_operation.create
    campaign_criterion.campaign.value = campaign_service.campaign_path(
        customer_id, campaign_id)

    # Besides using location_id, you can also search by location names from
    # GeoTargetConstantService.suggest_geo_target_constants() and directly
    # apply GeoTargetConstant.resource_name here. An example can be found
    # in get_geo_target_constant_by_names.py.
    campaign_criterion.location.geo_target_constant.value = (
        geo_target_constant_service.geo_target_constant_path(location_id))

    return campaign_criterion_operation

Ruby

def create_location(client, customer_id, campaign_id, location_id)
  criterion = client.resource(:CampaignCriterion)
  criterion.campaign = client.wrapper.string(
      client.path.campaign(customer_id, campaign_id))

  criterion.location = client.resource(:LocationInfo)
  # Besides using location_id, you can also search by location names from
  # GeoTargetConstantService.suggest_geo_target_constants() and directly
  # apply GeoTargetConstant.resource_name here. An example can be found
  # in get_geo_target_constant_by_names.rb.
  criterion.location.geo_target_constant = client.wrapper.string(
      client.path.geo_target_constant(location_id))

  return criterion
end

Google 偶尔可能会因为各种原因逐步淘汰一些地理位置条件,包括地理位置重组为更小(或更大)的区域、地缘政治变化等。您可以参考 GeoTargetConstant 对象中的 status 字段来确定地理位置的状态是 ENABLED 还是 REMOVAL_PLANNED。详细了解地理位置定位目标是如何被逐步淘汰的

按地理位置名称查找

您还可以使用 GeoTargetConstantService.SuggestGeoTargetConstants 按地理位置名称查找条件 ID。以下代码示例展示了如何根据地理位置名称来查找地理位置的条件 ID。

Java

private void runExample(GoogleAdsClient googleAdsClient) {
  GeoTargetConstantServiceClient geoTargetClient =
      googleAdsClient.getLatestVersion().createGeoTargetConstantServiceClient();

  SuggestGeoTargetConstantsRequest.Builder requestBuilder =
      SuggestGeoTargetConstantsRequest.newBuilder();

  // Locale is using ISO 639-1 format. If an invalid locale is given, 'en' is used by default.
  requestBuilder.setLocale(StringValue.of("en"));

  // A list of country codes can be referenced here:
  // https://developers.google.com/adwords/api/docs/appendix/geotargeting
  requestBuilder.setCountryCode(StringValue.of("FR"));

  requestBuilder
      .getLocationNamesBuilder()
      .addAllNames(
          Stream.of("Paris", "Quebec", "Spain", "Deutschland")
              .map(StringValue::of)
              .collect(Collectors.toList()));

  SuggestGeoTargetConstantsResponse response =
      geoTargetClient.suggestGeoTargetConstants(requestBuilder.build());

  for (GeoTargetConstantSuggestion suggestion : response.getGeoTargetConstantSuggestionsList()) {
    System.out.printf(
        "%s (%s,%s,%s,%s) is found in locale (%s) with reach (%d) for search term (%s).%n",
        suggestion.getGeoTargetConstant().getResourceName(),
        suggestion.getGeoTargetConstant().getName().getValue(),
        suggestion.getGeoTargetConstant().getCountryCode().getValue(),
        suggestion.getGeoTargetConstant().getTargetType().getValue(),
        suggestion.getGeoTargetConstant().getStatus().name(),
        suggestion.getLocale().getValue(),
        suggestion.getReach().getValue(),
        suggestion.getSearchTerm().getValue());
  }
}

C#

public void Run(GoogleAdsClient client)
{
    // Get the GeoTargetConstantServiceClient.
    GeoTargetConstantServiceClient geoService =
        client.GetService(Services.V1.GeoTargetConstantService);

    // Locale is using ISO 639-1 format. If an invalid locale is given,
    // 'en' is used by default.
    string locale = "en";

    // A list of country codes can be referenced here:
    // https://developers.google.com/adwords/api/docs/appendix/geotargeting
    string countryCode = "FR";

    String[] locations = { "Paris", "Quebec", "Spain", "Deutschland" };

    SuggestGeoTargetConstantsRequest request = new SuggestGeoTargetConstantsRequest()
    {
        Locale = locale,
        CountryCode = countryCode,
        LocationNames = new SuggestGeoTargetConstantsRequest.Types.LocationNames()
    };

    request.LocationNames.Names.AddRange(locations);

    try
    {
        SuggestGeoTargetConstantsResponse response =
            geoService.SuggestGeoTargetConstants(request);

        foreach (GeoTargetConstantSuggestion suggestion
            in response.GeoTargetConstantSuggestions)
        {
            Console.WriteLine(
                $"{suggestion.GeoTargetConstant.ResourceName} " +
                $"({suggestion.GeoTargetConstant.Name}, " +
                $"{suggestion.GeoTargetConstant.CountryCode}, " +
                $"{suggestion.GeoTargetConstant.TargetType}, " +
                $"{suggestion.GeoTargetConstant.Status}) is found in locale " +
                $"({suggestion.Locale}) with reach ({suggestion.Reach.Value}) " +
                $"for search term ({suggestion.SearchTerm}).");
        }
    }
    catch (GoogleAdsException e)
    {
        Console.WriteLine("Failure:");
        Console.WriteLine($"Message: {e.Message}");
        Console.WriteLine($"Failure: {e.Failure}");
        Console.WriteLine($"Request ID: {e.RequestId}");
    }
}

PHP

public static function runExample(
    GoogleAdsClient $googleAdsClient,
    array $locationNames,
    $locale,
    $countryCode
) {
    $geoTargetConstantServiceClient = $googleAdsClient->getGeoTargetConstantServiceClient();

    $names = [];
    foreach ($locationNames as $locationName) {
        $names[] = new StringValue(['value' => $locationName]);
    }
    $response = $geoTargetConstantServiceClient->suggestGeoTargetConstants(
        new StringValue(['value' => $locale]),
        new StringValue(['value' => $countryCode]),
        ['locationNames' => new LocationNames(['names' => $names])]
    );

    // Iterates over all geo target constant suggestion objects and prints the requested field
    // values for each one.
    foreach ($response->getGeoTargetConstantSuggestions() as $geoTargetConstantSuggestion) {
        /** @var GeoTargetConstantSuggestion $geoTargetConstantSuggestion */
        printf(
            "Found '%s' ('%s','%s','%s',%s) in locale '%s' with reach %d"
            . " for the search term '%s'.%s",
            $geoTargetConstantSuggestion->getGeoTargetConstant()->getResourceName(),
            $geoTargetConstantSuggestion->getGeoTargetConstant()->getNameValue(),
            $geoTargetConstantSuggestion->getGeoTargetConstant()->getCountryCodeValue(),
            $geoTargetConstantSuggestion->getGeoTargetConstant()->getTargetTypeValue(),
            GeoTargetConstantStatus::name(
                $geoTargetConstantSuggestion->getGeoTargetConstant()->getStatus()
            ),
            $geoTargetConstantSuggestion->getLocaleValue(),
            $geoTargetConstantSuggestion->getReachValue(),
            $geoTargetConstantSuggestion->getSearchTermValue(),
            PHP_EOL
        );
    }
}

Python

def main(client):
    gtc_service = client.get_service('GeoTargetConstantService', version='v1')

    location_names = (
        client.get_type('SuggestGeoTargetConstantsRequest',
                        version='v1').LocationNames())

    for location in ['Paris', 'Quebec', 'Spain', 'Deutschland']:
        location_name = location_names.names.add()
        location_name.value = location

    # Locale is using ISO 639-1 format. If an invalid locale is given,
    # 'en' is used by default.
    locale = client.get_type('StringValue', version='v1')
    locale.value = 'en'

    # A list of country codes can be referenced here:
    # https://developers.google.com/adwords/api/docs/appendix/geotargeting
    country_code = client.get_type('StringValue', version='v1')
    country_code.value = 'FR'

    results = gtc_service.suggest_geo_target_constants(
        locale, country_code, location_names=location_names)

    geo_target_constant_status_enum = client.get_type(
        'GeoTargetConstantStatusEnum').GeoTargetConstantStatus

    try:
        for suggestion in results.geo_target_constant_suggestions:
            geo_target_constant = suggestion.geo_target_constant
            print('%s (%s, %s, %s, %s) is found in locale (%s) with reach (%d) '
                  'from search term (%s).'
                  % (geo_target_constant.resource_name,
                     geo_target_constant.name.value,
                     geo_target_constant.country_code.value,
                     geo_target_constant.target_type.value,
                     geo_target_constant_status_enum.Name(
                         geo_target_constant.status),
                     suggestion.locale.value,
                     suggestion.reach.value,
                     suggestion.search_term.value))
    except google.ads.google_ads.errors.GoogleAdsException as ex:
        print('Request with ID "%s" failed with status "%s" and includes the '
              'following errors:' % (ex.request_id, ex.error.code().name))
        for error in ex.failure.errors:
            print('\tError with message "%s".' % error.message)
            if error.location:
                for field_path_element in error.location.field_path_elements:
                    print('\t\tOn field: %s' % field_path_element.field_name)
        sys.exit(1)

Ruby

def get_geo_target_constant_by_names()
  # GoogleAdsClient will read a config file from
  # ENV['HOME']/google_ads_config.rb when called without parameters
  client = Google::Ads::GoogleAds::GoogleAdsClient.new

  gtc_service = client.service(:GeoTargetConstant)

  location_names = client.resource(:LocationNames)
  ['Paris', 'Quebec', 'Spain', 'Deutschland'].each do |name|
    location_names.names << client.wrapper.string(name)
  end

  # Locale is using ISO 639-1 format. If an invalid locale is given,
  # 'en' is used by default.
  locale = client.wrapper.string('en')

  # A list of country codes can be referenced here:
  # https://developers.google.com/adwords/api/docs/appendix/geotargeting
  country_code = client.wrapper.string('FR')

  response = gtc_service.suggest_geo_target_constants(locale, country_code,
      location_names: location_names)

  response.geo_target_constant_suggestions.each do |suggestion|
    puts sprintf("%s (%s,%s,%s,%s) is found in locale (%s) with reach (%d)" \
        " from search term (%s).", suggestion.geo_target_constant.resource_name,
        suggestion.geo_target_constant.name,
        suggestion.geo_target_constant.country_code,
        suggestion.geo_target_constant.target_type,
        suggestion.geo_target_constant.status,
        suggestion.locale,
        suggestion.reach,
        suggestion.search_term)
  end
end

上述代码示例会生成以下输出内容:

geoTargetConstants/21167 (New York,US,State,ENABLED) is found in locale (en)
with reach (32900000) from search term (New York).

将广告系列定位到地理位置的邻近区域

有时候,您可能想要定位到一个比城市或国家/地区更具体的地方。例如,您可能想在自己商店周边 10 公里的范围内投放超市广告。在这种情况下,您可以使用邻近区域定位目标。创建邻近区域定位目标所需的代码类似于添加地理位置定位目标所需的代码,只是您必须创建的是 ProximityInfo 对象,而不是 LocationInfo 对象。

Java

private static CampaignCriterion buildProximityLocation(String campaignResourceName) {
  Builder builder =
      CampaignCriterion.newBuilder().setCampaign(StringValue.of(campaignResourceName));

  ProximityInfo.Builder proximityBuilder = builder.getProximityBuilder();
  proximityBuilder.setRadius(DoubleValue.of(10.0)).setRadiusUnits(ProximityRadiusUnits.MILES);

  AddressInfo.Builder addressBuilder = proximityBuilder.getAddressBuilder();
  addressBuilder
      .setStreetAddress(StringValue.of("38 avenue de l'Opéra"))
      .setCityName(StringValue.of("Paris"))
      .setPostalCode(StringValue.of("75002"))
      .setCountryCode(StringValue.of("FR"));

  return builder.build();
}

C#

private CampaignCriterion buildProximityCriterion(string campaignResourceName)
{
    ProximityInfo proximity = new ProximityInfo()
    {
        Address = new AddressInfo()
        {
            StreetAddress = "38 avenue de l'Opéra",
            CityName = "Paris",
            PostalCode = "75002",
            CountryCode = "FR"
        },
        Radius = 10d,
        // Default is kilometers.
        RadiusUnits = ProximityRadiusUnits.Miles
    };

    return new CampaignCriterion()
    {
        Campaign = campaignResourceName,
        Proximity = proximity
    };
}

PHP

private static function createProximityCampaignCriterionOperation($campaignResourceName)
{
    // Constructs a campaign criterion as a proximity.
    $campaignCriterion = new CampaignCriterion([
        'proximity' => new ProximityInfo([
            'address' => new AddressInfo([
                'street_address' => new StringValue(['value' => '38 avenue de l\'Opéra']),
                'city_name' => new StringValue(['value' => 'Paris']),
                'postal_code' => new StringValue(['value' => '75002']),
                'country_code' => new StringValue(['value' => 'FR']),
            ]),
            'radius' => new DoubleValue(['value' => 10.0]),
            // Default is kilometers.
            'radius_units' => ProximityRadiusUnits::MILES
        ]),
        'campaign' => new StringValue(['value' => $campaignResourceName])
    ]);

    return new CampaignCriterionOperation(['create' => $campaignCriterion]);
}

Python

def create_location_op(client, customer_id, campaign_id, location_id):
    campaign_service = client.get_service('CampaignService', version='v1')
    geo_target_constant_service = client.get_service('GeoTargetConstantService',
                                                     version='v1')

    # Create the campaign criterion.
    campaign_criterion_operation = client.get_type('CampaignCriterionOperation',
                                                   version='v1')
    campaign_criterion = campaign_criterion_operation.create
    campaign_criterion.campaign.value = campaign_service.campaign_path(
        customer_id, campaign_id)

    # Besides using location_id, you can also search by location names from
    # GeoTargetConstantService.suggest_geo_target_constants() and directly
    # apply GeoTargetConstant.resource_name here. An example can be found
    # in get_geo_target_constant_by_names.py.
    campaign_criterion.location.geo_target_constant.value = (
        geo_target_constant_service.geo_target_constant_path(location_id))

    return campaign_criterion_operation

Ruby

def create_proximity(client, customer_id, campaign_id)
  criterion = client.resource(:CampaignCriterion)
  criterion.campaign = client.wrapper.string(
      client.path.campaign(customer_id, campaign_id))

  criterion.proximity = client.resource(:ProximityInfo)
  criterion.proximity.address = client.resource(:AddressInfo)
  criterion.proximity.address.street_address =
      client.wrapper.string("38 avenue de l'Opéra")
  criterion.proximity.address.city_name = client.wrapper.string("Paris")
  criterion.proximity.address.postal_code = client.wrapper.string("75002")
  criterion.proximity.address.country_code = client.wrapper.string("FR")
  criterion.proximity.radius = client.wrapper.double(10)
  # Default is kilometers.
  criterion.proximity.radius_units = client.enum(:ProximityRadiusUnits)::MILES

  return criterion
end

获取地理位置定位目标

您可以使用 GoogleAdsService.Search 获取广告系列的地理位置定位目标,还可以在 WHERE 子句中过滤搜索结果。

SELECT
  campaign_criterion.campaign,
  campaign_criterion.location.geo_target_constant,
  campaign_criterion.proximity.geo_point.longitude_in_micro_degrees,
  campaign_criterion.proximity.geo_point.latitude_in_micro_degrees,
  campaign_criterion.proximity.radius,
  campaign_criterion.negative
FROM campaign_criterion
WHERE
  campaign_criterion.campaign = 'customers/{customer_id}/campaigns/{campaign_id}'
  AND campaign_criterion.type IN (LOCATION, PROXIMITY)

更新地理位置定位目标

要更新广告系列的地理位置定位目标,您需要获取现有地理位置定位目标的列表,并将其与新的定位目标列表进行比较。然后,您可以使用 remove 操作移除不需要的定位目标,接着使用 create 操作添加自己需要使用但现有广告系列中未提供的新地理位置定位目标。

排除地理位置定位目标

您虽然可以排除 LocationInfo,但不能排除 ProximityInfo。如果您想定位某个区域,例如整个美国,但又想排除其中的某个子区域,例如纽约市,则此功能就会非常有用。要排除某个区域,将 CampaignCriterion 中的 negative 字段设置为 true 即可。

定位多个地理位置区域

借助 LocationGroup,您可让广告系列定位多个地理位置区域。区域的中心位于广告系列的附加地址信息所定义的地理位置,或可选的 Feed 所定义的地理位置。

LocationGroup 上定义的半径取决于以各地理位置为中心划出的圆形区域,并包括 radius 对象、长度和 radius_units(以米或英里 LocationGroupRadiusUnitsEnum 为单位)。

您可以使用 geo_target_constant 字段中规定的地理位置定位条件 ID 列表过滤 LocationGroup 中的地理位置。如已定义,系统将不会定位任何给定条件 ID 之外的地理位置。

以下是创建 LocationGroup 时应注意的一些提示:

  • LocationGroup.feed 必须是 Feedresource_name(如果正在使用 Feed)。

  • LocationGroup.feed 只能在 CREATE 操作上进行转变。您无法在 UPDATE 操作上对该字段进行转变。

  • 由于以下任一原因,将 Feed 添加到 LocationGroup 时可能会发生 RESOURCE_NOT_FOUND 错误:

    • Feed 不存在。
    • Feed 无效。
    • Feed 没有任何映射到地理位置广告系列条件的属性。

只需查看 FeedMapping 条目,就可以确定 Feed 是否可用于 LocationGroup,至少一个 FeedMappingcriterion_type 应为 LOCATION_EXTENSION_TARGETING。以下是一个 GAQL 查询,会返回具有正确的 Feed 映射条件类型的 Feed:

SELECT
  feed.id,
  feed_mapping.criterion_type
FROM feed_mapping
WHERE
  feed.id = <feed id>
  AND feed_mapping.criterion_type = LOCATION_EXTENSION_TARGETING