報表串流

您可以透過 Search Ads 360 Reporting API 擷取實體和報表資料,方法有兩種。

本指南主要著重於從 SearchAds360Service 串流資料。以下是這兩種資料擷取方法的概略差異:

SearchAds360Service.SearchStream SearchAds360Service.Search
適合正式版程式碼
服務 SearchAds360Service SearchAds360Service
情境 擷取物件和報表 擷取物件和報表
回應 SearchAds360Row 物件的串流 SearchAds360Row 物件頁面
回應的欄位 僅限查詢中指定的項目 僅限查詢中指定的項目
每日上限 請參閱 API 限制與配額 請參閱「API 限制和配額」。

雖然 Search 可以傳送多個分頁要求來下載整份報表,但 SearchStream 只會傳送單一要求,並與 Search Ads 360 Reporting API 建立持續連線,不受報表大小影響。

如果是 SearchStream,系統會立即開始下載資料封包,並在資料緩衝區中快取整個結果。程式碼可以開始讀取緩衝資料,而無須等待整個串流完成。

SearchStream 可根據應用程式,消除要求 Search 回應的每個個別頁面所需的網路往返時間,進而提供比分頁更佳的效能,尤其是針對較大的報表。

範例

以包含 100,000 列的報表為例,下表列出這兩種方法之間的會計差異。

SearchStream 搜尋
頁面大小 不適用 每頁 10,000 列
API 要求數 1 項要求 10 項要求
API 回應數量 1 個連續串流 10 則回覆

效能因素

一般來說,我們建議使用 SearchStream 而非 Search,原因如下:

  • 單頁報表 (10,000 列以下):兩種方法之間沒有明顯的效能差異。

  • 針對多頁報表:SearchStream 通常會更快,因為可避免多次來回傳輸,且從磁碟快取讀取/寫入的因素較少。

頻率限制

這兩種方法的每日限制都遵循標準的 API 限制和配額。無論結果是否經過分頁或串流,單一查詢或報表都會計為一次作業。

串流範例

Java

// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package sample;

import com.beust.jcommander.Parameter;
import com.google.ads.searchads360.v0.lib.SearchAds360Client;
import com.google.ads.searchads360.v0.services.SearchAds360Row;
import com.google.ads.searchads360.v0.services.SearchAds360ServiceClient;
import com.google.ads.searchads360.v0.services.SearchSearchAds360StreamRequest;
import com.google.ads.searchads360.v0.services.SearchSearchAds360StreamResponse;
import com.google.api.gax.rpc.ServerStream;

/** Get campaign details using SearchStream. */
public class GetCampaignsStream {
  private static class GetCampaignsStreamParams extends CodeSampleParams {

    @Parameter(names = "--customerId", required = true)
    private String customerId;

    @Parameter(names = "--loginCustomerId")
    private String loginCustomerId;
  }

  public static void main(String[] args) {
    GetCampaignsStreamParams params = new GetCampaignsStreamParams();
    if (!params.parseArguments(args)) {
      // Optional: You may pass the loginCustomerId on the command line or specify a loginCustomerId
      // here (10 digits, no dashes). If neither are set, customerId will be used as
      // loginCustomerId.
      // params.loginCustomerId = Long.parseLong("INSERT_LOGIN_CUSTOMER_ID_HERE");
    }
    final String loginCustomerId = params.loginCustomerId;
    final String customerId = params.customerId;

    try {
      // Creates a SearchAds360Client with the specified loginCustomerId. If there's
      // no loginCustomerId, customerId will be used instead.
      final SearchAds360Client searchAds360Client =
          SearchAds360Client.newBuilder()
              .setLoginCustomerId(loginCustomerId == null ? customerId : loginCustomerId)
              .fromPropertiesFile()
              .build();
      // Creates the Search Ads 360 Service client.
      SearchAds360ServiceClient client = searchAds360Client.create();
      new GetCampaignsStream().runExample(client, customerId);
    } catch (Exception exception) {
      System.err.printf("Failed with exception: %s%n", exception);
      exception.printStackTrace();
      System.exit(1);
    }
  }

  private void runExample(SearchAds360ServiceClient searchAds360ServiceClient, String customerId) {
    // Creates a query that retrieves all campaigns under the customerId.
    String query = "SELECT campaign.name, campaign.id, campaign.status FROM campaign";
    SearchSearchAds360StreamRequest request =
        SearchSearchAds360StreamRequest.newBuilder()
            .setCustomerId(customerId)
            .setQuery(query)
            .build();

    // Issues a search stream request.
    ServerStream<SearchSearchAds360StreamResponse> stream =
        searchAds360ServiceClient.searchStreamCallable().call(request);

    for (SearchSearchAds360StreamResponse response : stream) {
      for (SearchAds360Row element : response.getResultsList()) {
        System.out.printf(
            "Campaign found with name '%s', ID %d, and status: %s.%n",
            element.getCampaign().getName(),
            element.getCampaign().getId(),
            element.getCampaign().getStatus());
      }
    }
  }
}

下載 GetCampaignsStream.java

Python

#!/usr/bin/env python
# Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Retrieves campaigns for a customer using a stream request."""

import argparse
import traceback
from google.ads.searchads360.v0.services.types.search_ads360_service import SearchSearchAds360StreamRequest
from util_searchads360 import SearchAds360Client


def main(client, customer_id) -> None:
  search_ads_360_service = client.get_service()

  query = """
      SELECT
        campaign.name,
        campaign.id,
        campaign.status
      FROM campaign"""

  request = SearchSearchAds360StreamRequest()
  request.customer_id = customer_id
  request.query = query

  # Issues a search stream request.
  results = search_ads_360_service.search_stream(request=request)

  for response in results:
    for result in response.results:
      campaign = result.campaign
      print(
          f'campaign "{campaign.name}" has id {campaign.id} and status {campaign.status.name}'
      )


if __name__ == "__main__":
  # SearchAds360Client will read the search-ads-360.yaml configuration file in
  # the home directory if none is specified.
  search_ads_360_client = SearchAds360Client.load_from_file()

  parser = argparse.ArgumentParser(
      description=("Retrieves campaigns for a customer."))
  # Arguments to provide to run the example.
  parser.add_argument(
      "-c",
      "--customer_id",
      type=str,
      required=True,
      help="The Search Ads 360 customer ID (10 digits, no dashes).",
  )

  parser.add_argument(
      "-l",
      "--login_customer_id",
      type=str,
      required=False,
      help="The Search Ads 360 login customer ID (10 digits, no dashes).",
  )

  args = parser.parse_args()

  search_ads_360_client.set_ids(args.customer_id, args.login_customer_id)

  try:
    main(search_ads_360_client, args.customer_id)
  except Exception:  # pylint: disable=broad-except
    traceback.print_exc()

下載 get_campaigns_stream.py