当前位置: 首页 > news >正文

用google-ads-python增删改查广告:10个高频广告操作代码示例,简单到直接复制就能用

用google-ads-python增删改查广告:10个高频广告操作代码示例,简单到直接复制就能用

【免费下载链接】google-ads-pythonGoogle Ads API Client Library for Python项目地址: https://gitcode.com/gh_mirrors/go/google-ads-python

📌 本文带你用google-ads-python(Google Ads API 官方 Python 客户端库)快速完成广告账户的增、删、改、查操作。它通过pip install google-ads一行命令安装,配合官方示例目录examples/下的大量可运行脚本,让你不用死磕 API 文档,复制修改就能上手。文章精选 10 个最高频的广告操作代码示例——从创建广告系列、查询广告,到修改、暂停、删除,全部一次讲透,新手也能照着直接跑通。

10 个高频广告操作速查表

先给你一张总览表,每个操作对应examples/basic_operations/目录下的一个官方示例文件,照着做即可:

#操作(增删改查)官方示例文件核心 Service
1查询所有广告系列(查)examples/basic_operations/get_campaigns.pyGoogleAdsService
2新增广告系列与预算(增)examples/basic_operations/add_campaigns.pyCampaignService
3新增广告组(增)examples/basic_operations/add_ad_groups.pyAdGroupService
4删除广告系列(删)examples/basic_operations/remove_campaign.pyCampaignService
5更新广告系列状态(改)examples/basic_operations/update_campaign.pyCampaignService
6查询响应式搜索广告(查)examples/basic_operations/get_responsive_search_ads.pyGoogleAdsService
7更新广告组出价(改)examples/basic_operations/update_ad_group.pyAdGroupService
8更新响应式搜索广告文案(改)examples/basic_operations/update_responsive_search_ad.pyAdService
9暂停单个广告(改)examples/basic_operations/pause_ad.pyAdGroupAdService
10统一异常处理(必备)各示例内置handle_googleads_exception

💡核心思路:查操作走GoogleAdsService的 GAQL 查询;增、删、改统一走各资源 Service 的mutate_*方法,通过 Operation 的create/update/remove三个槽位区分动作。

快速开始:安装 google-ads-python 并加载客户端

一步安装

pip install google-ads

两步配置(只需一次)

  1. 在用户主目录创建google-ads.yaml,填入developer_token(开发者令牌)、refresh_tokenclient_idclient_secret等认证信息;
  2. 运行时通过命令行参数-c传入数字形式的客户 ID(去掉横杠)。

所有示例都用下面这段代码加载客户端,这也是你写任何增删改查脚本的第一行

from google.ads.googleads.client import GoogleAdsClient googleads_client = GoogleAdsClient.load_from_storage(version="v24")

⚠️ 常见报错:"developer token is not valid" 或 "missing customer id",90% 的情况是google-ads.yaml没放对位置或客户 ID 带了横杠。

查询广告:get_campaigns 流式查询所有广告系列

"查"是最高频操作,核心是 GAQL(Google Ads Query Language)——写法像 SQL。examples/basic_operations/get_campaigns.py里的精华就 8 行:

ga_service = client.get_service("GoogleAdsService") query = """ SELECT campaign.id, campaign.name FROM campaign ORDER BY campaign.id""" for batch in ga_service.search_stream(customer_id=customer_id, query=query): for row in batch.results: print(f"Campaign with ID {row.campaign.id} and name \"{row.campaign.name}\" was found.")

💡 两个要点:

  • 小结果集ga_service.search(request=...)一次返回;大报表search_stream分批流式返回,防止内存爆掉;
  • 不确定该查哪些字段?官方示例examples/basic_operations/search_for_google_ads_fields.py专门演示了如何用 GAQL 搜索可用字段。

新增广告:add_campaigns 创建预算 + 广告系列

examples/basic_operations/add_campaigns.py演示了标准流程:先建预算,再建广告系列。两个关键片段:

# 1. 创建预算(可被多个广告系列共享) campaign_budget_operation = client.get_type("CampaignBudgetOperation") campaign_budget = campaign_budget_operation.create campaign_budget.name = f"Interplanetary Budget {uuid.uuid4()}" campaign_budget.amount_micros = 500000 # 金额单位为"微元",500000 ≈ 0.5 元 campaign_budget_service.mutate_campaign_budgets( customer_id=customer_id, operations=[campaign_budget_operation] )
# 2. 创建广告系列(先 PAUSED,加好定向和广告后再开启) campaign_operation = client.get_type("CampaignOperation") campaign = campaign_operation.create campaign.name = f"Interplanetary Cruise {uuid.uuid4()}" campaign.advertising_channel_type = client.enums.AdvertisingChannelTypeEnum.SEARCH campaign.status = client.enums.CampaignStatusEnum.PAUSED campaign.manual_cpc = client.get_type("ManualCpc") campaign.campaign_budget = budget_response.results[0].resource_name campaign.network_settings.target_google_search = True campaign.network_settings.target_search_network = True campaign_service.mutate_campaigns( customer_id=customer_id, operations=[campaign_operation] )

⚡ 记住一个铁律:新建广告系列一律先设PAUSED,等广告配齐再改ENABLED,避免广告还没配好就开始烧钱。

新增广告组:add_ad_groups 三行搞定

广告组是广告系列下的"分类容器",examples/basic_operations/add_ad_groups.pymain函数只有 20 行出头:

ad_group_operation = client.get_type("AdGroupOperation") ad_group = ad_group_operation.create ad_group.name = f"Earth to Mars cruises {uuid.uuid4()}" ad_group.status = client.enums.AdGroupStatusEnum.ENABLED ad_group.campaign = campaign_service.campaign_path(customer_id, campaign_id) ad_group.type_ = client.enums.AdGroupTypeEnum.SEARCH_STANDARD ad_group.cpc_bid_micros = 10000000 # 最高 CPC 出价 ad_group_service.mutate_ad_groups( customer_id=customer_id, operations=[ad_group_operation] )

💡campaign_path(customer_id, campaign_id)会自动拼出资源路径,比自己手写字符串安全可靠得多。

删除广告系列:remove_campaign 只需一个 remove 字段

examples/basic_operations/remove_campaign.py是全目录最精简的示例,删除逻辑只有 5 行:

campaign_operation = client.get_type("CampaignOperation") campaign_operation.remove = campaign_service.campaign_path( customer_id, campaign_id ) campaign_service.mutate_campaigns( customer_id=customer_id, operations=[campaign_operation] )

🧠 看出规律了吗?同一个mutate_campaigns入口,Operation 用create字段就是增、用update字段就是改、用remove字段就是删——这就是 Google Ads API 统一的mutate 模式

更新广告系列:update_campaign 别忘了 update_mask

修改操作的完整套路见examples/basic_operations/update_campaign.py

campaign_operation = client.get_type("CampaignOperation") campaign = campaign_operation.update campaign.resource_name = campaign_service.campaign_path(customer_id, campaign_id) campaign.status = client.enums.CampaignStatusEnum.PAUSED campaign.network_settings.target_search_network = False # 关键:告诉 API 只更新上面设置过的字段 client.copy_from( campaign_operation.update_mask, protobuf_helpers.field_mask(None, campaign._pb), ) campaign_service.mutate_campaigns( customer_id=customer_id, operations=[campaign_operation] )

⚠️update_mask(字段掩码)是"改"操作最容易踩的坑:Google Ads API 要求你明确声明"我到底改了哪些字段",漏掉它请求会直接报错。好消息是所有示例都用field_mask(None, campaign._pb)自动生成,你照抄就不会错。

查询响应式搜索广告:按广告类型筛选

examples/basic_operations/get_responsive_search_ads.py展示了如何用 GAQL 查具体广告素材,包括标题和描述文案:

query = """ SELECT ad_group.id, ad_group_ad.ad.id, ad_group_ad.ad.responsive_search_ad.headlines, ad_group_ad.ad.responsive_search_ad.descriptions, ad_group_ad.status FROM ad_group_ad WHERE ad_group_ad.ad.type = RESPONSIVE_SEARCH_AD AND ad_group_ad.status != REMOVED"""

💡 技巧:查询里加WHERE ad_group.id = {ad_group_id}可以把结果限定到某个广告组,排查素材问题时非常好用。

更新广告组:改状态、调出价

examples/basic_operations/update_ad_group.py演示最常见的"调整出价 + 暂停广告组"组合操作:

ad_group_operation = client.get_type("AdGroupOperation") ad_group = ad_group_operation.update ad_group.resource_name = ad_group_service.ad_group_path(customer_id, ad_group_id) ad_group.status = client.enums.AdGroupStatusEnum.PAUSED ad_group.cpc_bid_micros = cpc_bid_micro_amount client.copy_from( ad_group_operation.update_mask, protobuf_helpers.field_mask(None, ad_group._pb), ) ad_group_service.mutate_ad_groups( customer_id=customer_id, operations=[ad_group_operation] )

和"更新广告系列"完全同构:定位resource_name→ 改字段 → 生成update_maskmutate_*提交。

更新响应式搜索广告:批量换标题和描述

改广告文案是日常最高频的"改"操作,examples/basic_operations/update_responsive_search_ad.py给了标准写法:

ad = ad_operation.update ad.resource_name = ad_service.ad_path(customer_id, ad_id) headline_1 = client.get_type("AdTextAsset") headline_1.text = f"Cruise to Pluto #{uuid4().hex[:8]}" headline_1.pinned_field = client.enums.ServedAssetFieldTypeEnum.HEADLINE_1 headline_2 = client.get_type("AdTextAsset") headline_2.text = "Tickets on sale now" ad.responsive_search_ad.headlines.extend([headline_1, headline_2, headline_3]) ad.responsive_search_ad.descriptions.extend([description_1, description_2]) ad.final_urls.append("https://www.example.com")

💡pinned_field可以"钉住"某条标题固定展示在第一位,A/B 测试文案时非常实用。

暂停广告:pause_ad 精准停掉单个广告

想只停某一条广告、不动整个广告组?examples/basic_operations/pause_ad.py演示了粒度最细的"改状态":

ad_group_ad_operation = client.get_type("AdGroupAdOperation") ad_group_ad = ad_group_ad_operation.update ad_group_ad.resource_name = ad_group_ad_service.ad_group_ad_path( customer_id, ad_group_id, ad_id ) ad_group_ad.status = client.enums.AdGroupAdStatusEnum.PAUSED client.copy_from( ad_group_ad_operation.update_mask, protobuf_helpers.field_mask(None, ad_group_ad._pb), ) ad_group_ad_service.mutate_ad_group_ads( customer_id=customer_id, operations=[ad_group_ad_operation] )

📝 注意路径参数多了一层:广告挂在广告组下面,所以是ad_group_ad_path(customer_id, ad_group_id, ad_id)

错误处理:让报错信息一眼看懂

所有示例都内置了同一个异常处理函数,建议直接抄进你的项目:

def handle_googleads_exception(exception): print( f'Request with ID "{exception.request_id}" failed with status ' f'"{exception.error.code().name}" and includes the following errors:' ) for error in exception.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}")

它会把 Google 返回的错误消息 + 出错字段路径逐条打印出来,比如"budget amount too small"会精确指向是哪个字段——排查问题的效率直接翻倍。

常见问题 FAQ

Q1:版本号 v24 是从哪来的?A:load_from_storage(version="v24")指定 API 版本。库内同时提供 v21 到 v25 多个版本目录(如google/ads/googleads/v24/),示例当前统一使用 v24,升级版本时只需改这一处。

Q2:批量操作几百条广告会不会很慢?A:mutate_*方法本身就接受 Operation 列表,一次请求可以提交多条增删改;更大的批量场景可以参考examples/campaign_management/add_complete_campaigns_using_batch_job.py使用异步 Batch Job,以及examples/reporting/parallel_report_download.py并行拉取报表。

Q3:能写异步(async)脚本吗?A:可以。examples/asyncio/目录提供了async_search.pyasync_add_campaigns.py等完整示例,用GoogleAdsClient.load_from_storage后直接await即可。

Q4:金额单位总是搞混?A:Google Ads API 的金额单位是"微元"(1 元 = 1,000,000 微元),所以amount_micros = 500000表示 0.5 元。

写在最后

10 个示例串起来就是一条完整的广告运维动线:配置客户端 → GAQL 查询 → 建预算建广告系列 → 建广告组 → 改状态调出价 → 换广告文案 → 暂停 → 删除。掌握mutate_*+ Operation 的统一模式,剩下就是换 Service 和换字段。

🚀 下一步建议:从examples/basic_operations/跑通第一个查询开始,再按需进入examples/advanced_operations/(高级操作)、examples/error_handling/(异常处理)目录深入。祝你早日写出第一个自动化投放脚本!

【免费下载链接】google-ads-pythonGoogle Ads API Client Library for Python项目地址: https://gitcode.com/gh_mirrors/go/google-ads-python

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

http://www.cnnetsun.cn/news/4172257.html

相关文章:

  • 为什么国旗有4个字符却只有1个字素簇?unicode-segmentation字素簇完整教程
  • meta与EnTT组合实战:打造C++ ECS游戏引擎的运行时内省与属性编辑基础
  • Physical Token经济学:破解机器人规模化瓶颈的能力复用新范式
  • MobileInfo 设备指纹实践:如何基于 Build 与 Serial 生成不碰撞的设备唯一 ID
  • 单机多GPU利用率最大化:Distributed-TensorFlow-Guide中Worker的GPU分配实战教程
  • 阿里云RTC LTR技术解析:硬件解码支持下的弱网视频抗丢包方案
  • 大模型Agent技术面试核心问题与实战解析
  • Vue+Flask求职推荐系统:Apriori算法实战
  • 人工变量法第二次迭代详解:从单纯形表到最优解判定
  • 在SUN 7149A CRT显示器上播放《九龙珠》:高行频驱动与信号配置实践
  • 美赛建模思维实战:从问题分析到模型构建的完整指南
  • 大模型面试8小时速通:知识图谱与高频题型解析
  • 自我认知面试技巧与STAR-L法则应用指南
  • Flutter混合开发中Gradle配置冲突:Cannot change attributes错误深度解析与解决方案
  • invest线性单位投影问题:提示数据集必须以线性单位投影...如何解决?
  • 踩坑记录——eBPF实现实时数据主从同步
  • Revit建筑设计思维课堂:从参数化建模到BIM协同的实战进阶指南
  • PyTorch实战:从零构建八大核心神经网络模型(CNN/RNN/GAN/Transformer等)
  • 北斗导航 | 基于赏金猎人优化算法(Bounty Hunter Optimizer, BHO)的接收机自主完好性监测算法研究,原理,公式,完整matlab代码,参考文献等
  • S-JEPA视觉自监督中GMM软目标映射:非最大概率组件的工程实践与权衡
  • 计算机组成原理核心精讲:从冯诺依曼到Cache与流水线
  • AI安全技术栈解析:从自动化检测到企业级部署实践
  • C++模板编程:从泛型思维到STL容器实现全解析
  • SA-ADP: Sensitivity-Aware Adaptive Differential Privacy for Large Language Models
  • 设计模式——装饰模式
  • Makefile头文件依赖自动生成:-MMD与-include实战指南
  • 从FFmpeg到Pillow:构建高效自动化文件格式转换技术栈
  • FPGA FIFO 为什么会多写一拍、少读一拍?从指针回绕到 Gray 码讲透满空判断
  • 【Python量化实战 #05】财报三大报表看花眼?3 步用 Python 拉齐资产负债表、利润表与现金流
  • 金融大模型安全框架FinHarness:为AI智能体编织实时防护网