Google Ads API Python 快速上手:环境配置、google-ads.yaml凭证管理、GAQL 查询与错误排查(skills 仓库实战指南)
【免费下载链接】skillsAgent Skills for Google products and technologies项目地址: https://gitcode.com/GitHub_Trending/skills29/skills
本文是 GitHub 推荐项目精选 skills 仓库中 Google Ads API Python Setup Reference 的完整实战讲解。文章以该参考文档为核心骨架,围绕 Python 官方客户端库google-ads的安装、凭证配置、首个 GAQL 查询脚本的编写与运行、以及常见错误的排查展开,并融入仓库内 SKILL.md 中关于凭证获取、login_customer_id层级路由、动态版本解析等上下文,帮助你从零开始跑通"查询广告系列"的第一个 Google Ads API 请求。读完本文,你将掌握 Python 环境下 Google Ads API 的完整接入流程,并能独立定位USER_PERMISSION_DENIED、DEVELOPER_TOKEN_NOT_APPROVED等高频故障。
一、前置条件:Python 版本与包管理器
在开始之前,请确认你的开发环境满足以下两个基础条件:
- Python:版本需达到最低支持版本(
MINIMUM_PYTHON_VERSION)及以上。该占位符并非硬编码值——根据 SKILL.md 的"动态运行时版本解析(Dynamic Language Runtime Version Resolution)"要求,应实时查阅官方 Supported Client Library Versions 文档页,扫描其中Python客户端库对应的最低支持运行时版本(例如 Python 3.8+),并将该版本替换到最终输出中。若官方页面不可达,仓库记录的离线兜底版本为Python 3.9+。 - 包管理器:
pip。
[!IMPORTANT]Action Required: 动态 Python 版本解析在向用户呈现前置条件之前,必须动态解析最低 Python 版本,以符合当前支持周期:
- 访问 Supported Client Library Versions 文档页;
- 扫描页面/表格中Python客户端库,识别最低支持的 Python 运行时版本;
- 在最终输出中用动态获取的版本替换
MINIMUM_PYTHON_VERSION占位符。
此外,整个集成过程中涉及的所有 API 版本与语言运行时版本都禁止硬编码(例如v24、Python 3.8+),必须在执行开始时动态解析最新稳定版本。这与仓库 SKILL.md 中"Crucial Requirement: Dynamic Version Resolution & Runtime Resolution"的约束保持一致。
二、Step 1:环境与安装
[!TIP]最佳实践:始终在虚拟环境(
venv)中安装客户端库,以避免与其他系统包产生依赖冲突。这对于在共享工作区中运行的自动化 Agent 尤其重要。
1. 创建并激活虚拟环境
在项目根目录执行以下命令:
python3 -m venv .venv source .venv/bin/activate2. 安装官方客户端库
安装官方 Google Ads Python 客户端库:
python -m pip install google-ads安装包名为google-ads(对应 SKILL.md 中 Python 轨道指定的 Package 名称)。虚拟环境隔离了库依赖,后续运行脚本时也必须保持该环境处于激活状态,否则会出现ModuleNotFoundError(详见本文"错误排查"一节)。
三、Step 2:配置(google-ads.yaml与多种加载方式)
在项目根目录创建一个名为google-ads.yaml的文件。Python 客户端库为GoogleAdsClient的初始化提供了四种加载方式:
- YAML 文件(
load_from_storage):按如下顺序解析配置文件——(1) 显式传给load_from_storage('/path/to/google-ads.yaml')的路径;(2)GOOGLE_ADS_CONFIGURATION_FILE_PATH环境变量指定的路径;(3) 默认的$HOME/google-ads.yaml。 - 环境变量(
load_from_env):读取大写GOOGLE_ADS_前缀的变量(例如GOOGLE_ADS_DEVELOPER_TOKEN、GOOGLE_ADS_CLIENT_ID)。(注意:如果设置了GOOGLE_ADS_CONFIGURATION_FILE_PATH,load_from_env会改为从该 YAML 文件加载。) - 字典(
load_from_dict):直接接受一个包含凭证的 Python 字典。 - YAML 字符串(
load_from_string):接受内存中的原始 YAML 字符串。
[!IMPORTANT]封闭式工作区规则(Hermetic Workspace Rule):对于自包含的项目环境,最佳实践是将
google-ads.yaml放在项目根目录,并显式加载它。
向文件中填入你的凭证:
# google-ads.yaml developer_token: INSERT_DEVELOPER_TOKEN_HERE client_id: INSERT_OAUTH2_CLIENT_ID_HERE client_secret: INSERT_OAUTH2_CLIENT_SECRET_HERE refresh_token: INSERT_OAUTH2_REFRESH_TOKEN_HERE # Optional: Un-comment if you are accessing a client account through a manager account # login_customer_id: INSERT_LOGIN_CUSTOMER_ID_HERE use_proto_plus: true配置参数说明:
| 配置键 | 必填 | 含义 |
|---|---|---|
developer_token | 是 | 开发者令牌,标识你的开发者访问权限与 API 配额,取自 Manager 账户的 API Center |
client_id/client_secret | 是 | OAuth2 客户端 ID 与密钥,标识你的应用,来自 Google Cloud Console |
refresh_token | 是 | 长期有效的 OAuth2 刷新令牌,用于自动换取短时访问令牌 |
login_customer_id | 否 | 10 位 Manager 账户 ID,通过经理账户访问客户账户时必填 |
use_proto_plus | 推荐 | 启用 proto-plus 风格的响应对象,使字段访问更贴近 Python 习惯(如row.campaign.id) |
关于凭证本身的获取流程(Developer Token、OAuth2 Client ID/Secret、Refresh Token、Client Customer ID 与 Login Customer ID 五项参数),SKILL.md 给出了完整指引:
Developer Token:登录 Google AdsManager 账户后直接访问 API Center(
https://ads.google.com/aw/apicenter)复制。若令牌状态为 "Pending"(未审批),只能用于 Google Ads 测试账户,否则调用生产账户会报DEVELOPER_TOKEN_NOT_APPROVED。OAuth2 Client ID & Secret:在 Google Cloud Console 中创建/选择项目 → 启用Google Ads API→ 配置 OAuth Consent Screen(用户类型选External,Publishing Status 设为Testing,并必须将登录 Google Ads 的邮箱添加为Test User)→ 在 Credentials 中创建类型为Desktop App的 OAuth Client ID → 下载 JSON 保存为
client_secrets.json。OAuth2 Refresh Token:使用
gcloudCLI 执行授权流程:gcloud auth application-default login \ --scopes=https://www.googleapis.com/auth/adwords,https://www.googleapis.com/auth/cloud-platform \ --client-id-file=client_secrets.json在浏览器中登录测试用户邮箱完成授权后,
gcloud会提示凭证保存位置(通常为~/.config/gcloud/application_default_credentials.json),从中复制refresh_token。Client Customer ID:10 位数字、不带连字符(如
1234567890而非123-456-7890),在 Google Ads UI 右上角用户图标旁可见。令牌处于 Pending 状态时,此 ID必须是测试账户的 Customer ID。Login Customer ID:10 位 Manager 账户 ID。若你的 OAuth 凭证(与开发者令牌)属于 Manager 账户,但要查询其下的子/客户账户,此参数必填。
[!CAUTION]防止
USER_PERMISSION_DENIED:若通过 Manager 账户层级访问客户账户,必须设置该参数。login_customer_id=Manager账户 ID,client_customer_id=子/客户账户 ID。在 manager-client 层级中留空login_customer_id是权限错误的第一大原因。
四、Step 3:编写快速入门脚本
创建名为get_campaigns.py的文件。
[!IMPORTANT]规则 1:规范化 Customer ID在将 Client Customer ID 传给 API 之前,必须先去掉所有连字符进行规范化(例如将
123-456-7890转换为1234567890)。下面的脚本在入口点已自动处理这一点。规则 2:配置文件路径下面的脚本配置为先在当前工作目录查找
google-ads.yaml,再回退到环境变量或默认搜索路径。
import argparse import os import sys from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException def main(client, customer_id): # Initialize the Google Ads Service googleads_service = client.get_service("GoogleAdsService") # Define the GAQL query query = "SELECT campaign.id, campaign.name, campaign.status FROM campaign ORDER BY campaign.id" print("Querying Google Ads API...") try: # Execute the search stream request stream = googleads_service.search_stream(customer_id=customer_id, query=query) for response in stream: for row in response.results: print(f"Campaign found: ID = {row.campaign.id}, Name = '{row.campaign.name}', Status = {row.campaign.status.name}") except GoogleAdsException as ex: print(f"Request ID '{ex.request_id}' failed with status '{ex.error.code().name}':") for error in ex.failure.errors: print(f"\tError: {error.message}") sys.exit(1) if __name__ == '__main__': # Determine configuration file path (prefer local workspace config) local_config = os.path.join(os.getcwd(), "google-ads.yaml") if os.path.exists(local_config): # Load explicitly from local workspace googleads_client = GoogleAdsClient.load_from_storage(local_config) elif "GOOGLE_ADS_DEVELOPER_TOKEN" in os.environ: # Load from environment variables googleads_client = GoogleAdsClient.load_from_env() else: # Fallback to default search paths (GOOGLE_ADS_CONFIGURATION_FILE_PATH or $HOME/google-ads.yaml) googleads_client = GoogleAdsClient.load_from_storage() parser = argparse.ArgumentParser(description="Lists campaigns for a specified customer ID.") parser.add_argument("-c", "--customer_id", required=True, help="10-digit customer ID.") args = parser.parse_args() # Normalize customer ID by removing hyphens before passing to main normalized_customer_id = args.customer_id.replace("-", "") main(googleads_client, normalized_customer_id)脚本要点解读
- 查询服务初始化:
client.get_service("GoogleAdsService")返回 API 服务对象,用于执行 GAQL 查询。 - GAQL 查询:
SELECT campaign.id, campaign.name, campaign.status FROM campaign ORDER BY campaign.id使用 Google Ads Query Language(GAQL)声明式地选取广告系列资源。REST 轨道(见 references/rest.md)使用完全相同的查询串作为 POST body 中的query字段,两种方式共享同一套 GAQL 语法。 - 流式搜索:
search_stream以流式方式返回结果(对应 REST 的googleAds:searchStream端点),外层迭代response、内层迭代response.results逐行读取数据。 - 异常处理:
GoogleAdsException暴露了request_id(对排查与联系官方支持至关重要,REST 路径下对应响应头中的request-id)、error.code().name()(错误码枚举名)与failure.errors(逐条错误消息)。 - 配置加载优先级:脚本入口处的三段式逻辑——本地工作区
google-ads.yaml优先 → 检测到GOOGLE_ADS_DEVELOPER_TOKEN环境变量时用load_from_env()→ 否则回退到默认搜索路径。这与本文第三节介绍的加载顺序一一对应。 - ID 规范化:
args.customer_id.replace("-", "")在进入main前移除所有连字符,遵循规则 1。
五、Step 4:运行脚本
在终端中执行脚本,传入客户 ID 作为参数。
[!NOTE] 运行前请确保虚拟环境已激活(
source .venv/bin/activate)。
python get_campaigns.py -c XXXXXXXXXX(将XXXXXXXXXX替换为你的 10 位客户 ID,带或不带连字符均可。)
六、Step 5:验证与错误排查
期望的成功输出
执行成功后,应看到类似如下的输出:
Querying Google Ads API... Campaign found: ID = 123456789, Name = 'Search - Brand - US', Status = ENABLED Campaign found: ID = 987654321, Name = 'Display - Remarketing', Status = PAUSED常见错误对照表
| 错误症状 / 错误码 | 根因 | 解决方案 |
|---|---|---|
FileNotFoundException/File not found | 库找不到google-ads.yaml | 确保文件确切命名为google-ads.yaml,并放在运行脚本的目录或$HOME目录下 |
DEVELOPER_TOKEN_NOT_APPROVED | 使用未审批("Pending")的开发者令牌调用生产账户(生产调用需要 Explorer、Basic 或 Standard 访问权限) | 使用测试账户(允许 Pending 令牌)或等待令牌审批 |
NOT_ADS_USER | 生成刷新令牌所用的 OAuth2 用户凭证无权访问指定的-c/--customer_id | 使用有权访问目标 Ads 账户的 Google 账户重新执行 OAuth2 授权流程 |
ModuleNotFoundError: No module named 'google' | Python 找不到已安装的库 | 很可能是库安装在虚拟环境中,却用全局 Python 解释器运行脚本;确保先执行source .venv/bin/activate |
两类高频错误的深入排查
1.USER_PERMISSION_DENIED
- 症状:执行 API 请求(如检索广告系列)时收到
USER_PERMISSION_DENIED。 - 可能原因:认证的 OAuth2 用户通过Manager 账户间接拥有目标客户账户的访问权,但请求头中缺少 Manager 账户 ID。
按 SKILL.md 的诊断清单,回复用户时应包含:解释层级关系(认证用户属于目标客户账户之上的 Manager 账户)→ 在配置文件中将 10 位 Manager 账户 ID 加入login_customer_id→ 解释路由逻辑(login_customer_id让 API 通过 Manager 账户路由 OAuth 凭证以校验对子账户的访问)→ 给出修复配置示例:
developer_token: INSERT_DEVELOPER_TOKEN_HERE client_id: INSERT_OAUTH2_CLIENT_ID_HERE client_secret: INSERT_OAUTH2_CLIENT_SECRET_HERE refresh_token: INSERT_OAUTH2_REFRESH_TOKEN_HERE # Add your 10-digit Manager Account ID here to resolve USER_PERMISSION_DENIED: login_customer_id: INSERT_LOGIN_CUSTOMER_ID_HERE[!CAUTION]安全护栏:任何情况下都不应通过暴露原始密码、创建新的未审批开发者令牌、或扩大 OAuth scope(超出标准
adwordsscope)来绕过该错误。
2.DEVELOPER_TOKEN_NOT_APPROVED
- 症状:脚本以
DEVELOPER_TOKEN_NOT_APPROVED报错。 - 可能原因:开发者令牌处于 "Pending"(未审批)状态,却试图访问真实的生产 Google Ads 账户。
排查时需明确说明:未审批的 Pending 令牌功能完整,但仅限 Google Ads 测试账户;生产账户必须由 Google Ads API 合规团队审批为Explorer Access、Basic Access或Standard Access三个级别之一(不可简化为"至少 Basic")。沙箱搭建步骤为:创建Test Manager 账户(无需审批令牌)→ 在其下创建Test Client 账户→ 在配置中使用 Test Client Customer ID。该限制由 Google 服务端强制执行,修改客户端库源码或使用第三方包装器均无法绕过,也不建议这样做。
[!NOTE]静态诊断约束:根据 SKILL.md,排查时不应执行 bash 命令、运行本地测试脚本或在工作区复现错误,而应完全依赖静态代码分析、配置审查与上述诊断指南,以避免陷入反复失败的执行循环。
七、纵向扩展:Python 之外的接入路径
理解 Python 快速入门后,可顺带了解仓库中的其他接入方式,它们共享同一套凭证体系与 GAQL 语法:
其他官方客户端库:本技能支持 Python、Java、.NET、PHP、Ruby、Perl 六种官方客户端库与直接 REST 两种轨道(见 SKILL.md),对应参考文档位于 references/ 目录下(如 java.md、ruby.md 等)。各语言的关键差异在于配置文件格式与加载机制:例如 Java 使用
ads.properties(键名为api.googleads.developerToken等)并通过fromPropertiesFile()加载,且需按 API 版本替换导入包名中的vXX占位符。直接 REST:若运行环境不适合客户端库(轻量 serverless 函数、自定义语言栈或受限运行时),可参考 references/rest.md:先通过 Service Account 流程(推荐)或用户认证流程换取短时
access_token,再向https://googleads.googleapis.com/vXX/customers/{customer_id}/googleAds:searchStream发起携带developer-token、Authorization: Bearer、login-customer-id头的POST请求,body 中放入与本文相同的 GAQLquery。AI 助手 / MCP 集成:如果你的目标是用自然语言让 AI 助手(如 Gemini、Cursor、Claude Code)查询 Google Ads,SKILL.md 明确指示:不要编写自定义脚本或客户端库代码,而是直接转用仓库中的 google-ads-api-mcp-setup 技能安装官方 Google Ads MCP Server(
pipx install google-ads-mcp),该服务器通过 MCPstdio传输暴露list_accessible_customers、get_resource_metadata、search三个只读工具。查询与诊断类工作流(如 google-ads-api-account-diagnostics)也都是基于 GAQL 的search调用,例如通过customer_client资源筛选启用的客户端账户:SELECT customer_client.id, customer_client.descriptive_name, customer_client.status, customer_client.manager FROM customer_client WHERE customer_client.status = 'ENABLED' AND customer_client.manager = FALSE
八、小结
通过本文,你已完整走通 Google Ads API 的 Python 快速入门链路:venv虚拟环境与google-ads安装 →google-ads.yaml凭证文件与四种GoogleAdsClient加载方式 →get_campaigns.py中 GAQL 流式查询与异常处理 → 四种常见错误的对照排查。整个流程与仓库 google-ads-api-quickstart 技能的指导原则完全一致:凭证获取参考 SKILL.md 的 Step 1,动态版本解析遵循其"禁止硬编码"约束,login_customer_id与 Pending 令牌规则贯穿始终。
掌握了 Python 客户端的这一最小闭环后,你可以向两个方向自然延伸:一是对照 references/ 中的 Java、.NET、PHP、Ruby、Perl 或 REST 文档迁移到其他技术栈;二是通过 google-ads-api-mcp-setup 将同一套凭证接入 MCP 生态,让 AI 助手以自然语言完成后续的账户查询与性能诊断(参考 google-ads-api-account-diagnostics)。
【免费下载链接】skillsAgent Skills for Google products and technologies项目地址: https://gitcode.com/GitHub_Trending/skills29/skills
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考