You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Python基于新版Google Ads API自动化获取Geo Performance Report等性能报告?

适配新版Google Ads API获取性能报表的解决方案

我明白你在把旧版Google Ads API(v201809)的报表逻辑迁移到新版时碰了壁——新版API彻底抛弃了旧版的ReportDownloader和预定义报表类型,改用**GAQL(Google Ads Query Language)**来实现数据查询,灵活性更强但写法和旧版差异很大。下面给你一套完整的可运行方案,包含关键词报表、地域报表等常见性能报表的获取流程。

核心思路说明

新版Google Ads API没有了KEYWORDS_PERFORMANCE_REPORT这种预定义报表类型,你需要用GAQL编写类似SQL的查询语句,指定要获取的字段、过滤条件(比如日期范围),然后通过GoogleAdsService的search_stream或search方法拉取数据,最后转换成DataFrame格式。

完整实现代码

import io
import sys
import pandas as pd
from datetime import datetime, timedelta
from google.ads.googleads.client import GoogleAdsClient
from google.ads.googleads.errors import GoogleAdsException

def fetch_googleads_report(client, customer_id, gaql_query):
    """
    通过新版Google Ads API获取报表数据并转换为DataFrame
    Args:
        client: GoogleAdsClient实例
        customer_id: 客户ID(不带连字符)
        gaql_query: 完整的GAQL查询语句
    Returns:
        pandas.DataFrame: 报表数据
    """
    ga_service = client.get_service("GoogleAdsService")
    results = []
    
    try:
        # 使用search_stream处理大数据量,避免内存溢出
        response = ga_service.search_stream(customer_id=customer_id, query=gaql_query)
        for batch in response:
            for row in batch.results:
                # 将Google Ads API返回的行数据转换为字典
                row_dict = {}
                for field in row._pb.DESCRIPTOR.fields:
                    value = getattr(row, field.name)
                    # 处理不同类型的字段值(比如枚举、消息类型)
                    if field.type == field.TYPE_ENUM:
                        enum_value = client.get_type(field.message_type.name).Name(value)
                        row_dict[field.name] = enum_value
                    elif field.type == field.TYPE_MESSAGE:
                        # 处理嵌套字段,比如metrics.clicks
                        for sub_field in value._pb.DESCRIPTOR.fields:
                            sub_value = getattr(value, sub_field.name)
                            row_dict[f"{field.name}_{sub_field.name}"] = sub_value
                    else:
                        row_dict[field.name] = value
                results.append(row_dict)
        
        # 转换为DataFrame
        df = pd.DataFrame(results)
        return df
    except GoogleAdsException as ex:
        print(
            f'Request with ID "{ex.request_id}" failed with status '
            f'"{ex.error.code().name}" and includes the following errors:'
        )
        for error in ex.failure.errors:
            print(f'\tError with message "{error.message}".')
            if error.location:
                for field_path_element in error.location.field_path_elements:
                    print(f"\t\tOn field: {field_path_element.field_name}")
        sys.exit(1)

def main(client, customer_id):
    # 定义日期范围
    today = datetime.now().date()
    yesterday = today - timedelta(days=1)
    start_date = "2019-01-01"
    end_date = yesterday.strftime("%Y-%m-%d")

    # --------------------------
    # 1. 获取关键词性能报表(对应旧版KEYWORDS_PERFORMANCE_REPORT)
    # --------------------------
    keyword_gaql = f"""
        SELECT
            segments.date,
            customer.descriptive_name,
            ad_group.id,
            ad_group.name,
            ad_group.status,
            campaign.id,
            campaign.name,
            campaign.status,
            ad_group_criterion.cpc_bid_micros,
            ad_group_criterion.keyword.text,
            ad_group_criterion.keyword.match_type,
            ad_group_criterion.status,
            metrics.clicks,
            metrics.conversions,
            metrics.cost_micros,
            metrics.conversion_value,
            metrics.impressions,
            metrics.view_through_conversions,
            ad_group_criterion.quality_info.quality_score,
            ad_group_criterion.quality_info.search_impression_share,
            ad_group_criterion.quality_info.first_page_cpc_micros,
            ad_group_criterion.quality_info.first_position_cpc_micros,
            ad_group_criterion.quality_info.top_of_page_cpc_micros
        FROM keyword_view
        WHERE segments.date BETWEEN '{start_date}' AND '{end_date}'
          AND ad_group_criterion.status != 'REMOVED'
    """
    
    keyword_df = fetch_googleads_report(client, customer_id, keyword_gaql)
    # 处理微单位转换(比如cost_micros转为美元,除以1e6)
    keyword_df["ad_group_criterion_cpc_bid_micros"] = keyword_df["ad_group_criterion_cpc_bid_micros"] / 1e6
    keyword_df["metrics_cost_micros"] = keyword_df["metrics_cost_micros"] / 1e6
    keyword_df["ad_group_criterion_quality_info_first_page_cpc_micros"] = keyword_df["ad_group_criterion_quality_info_first_page_cpc_micros"] / 1e6
    
    print("关键词报表前5行:")
    print(keyword_df.head())
    keyword_df.to_csv("keywords_performance_report.csv", index=False)

    # --------------------------
    # 2. 获取地域性能报表(对应旧版GEO_PERFORMANCE_REPORT)
    # --------------------------
    geo_gaql = f"""
        SELECT
            segments.date,
            customer.descriptive_name,
            campaign.id,
            campaign.name,
            campaign.status,
            geo_target_constant.country_code,
            geo_target_constant.name,
            metrics.clicks,
            metrics.conversions,
            metrics.cost_micros,
            metrics.impressions,
            metrics.conversion_value
        FROM geo_view
        WHERE segments.date BETWEEN '{start_date}' AND '{end_date}'
    """
    
    geo_df = fetch_googleads_report(client, customer_id, geo_gaql)
    geo_df["metrics_cost_micros"] = geo_df["metrics_cost_micros"] / 1e6
    
    print("\n地域报表前5行:")
    print(geo_df.head())
    geo_df.to_csv("geo_performance_report.csv", index=False)

if __name__ == "__main__":
    # 加载配置文件(google-ads.yaml需要放在指定路径,或者传入path参数)
    try:
        googleads_client = GoogleAdsClient.load_from_storage(path="mypath/google-ads.yaml")
    except FileNotFoundError:
        print("请确保google-ads.yaml配置文件路径正确!")
        sys.exit(1)
    
    # 替换为你的客户ID(不带连字符)
    customer_id = "#######"
    
    main(googleads_client, customer_id)

关键细节说明

  1. GAQL查询编写:
    • 你可以通过官方的查询构建工具可视化生成GAQL语句,避免字段拼写错误。
    • 不同报表对应不同的FROM子句:关键词报表用keyword_view,地域报表用geo_view,广告报表用ad_view,活动报表用campaign_view。
  2. 字段单位转换:新版API中涉及金额、出价的字段都是以微单位存储的(比如1美元=1,000,000微美元),所以需要除以1e6转换为实际金额。
  3. 数据拉取方式:推荐用search_stream而不是search,因为当数据量很大时,search_stream会分批返回结果,避免内存溢出。
  4. 错误处理:保留了GoogleAdsException的捕获逻辑,方便排查API调用失败的原因。

迁移注意事项

  • 旧版的ExternalCustomerId对应新版的customer.id,但通常你已经传入了customer_id,所以不需要额外查询。
  • 旧版的Labels字段在新版中需要通过ad_group_criterion.labels或campaign.labels关联查询,如果你需要标签数据,可以在GAQL中添加SELECT ... ad_group_criterion.labels ...并处理嵌套字段。

内容的提问来源于stack exchange,提问作者LIONEL JOSEPH

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 19:17:51