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

Selenium无法识别Google Ads中动态加载的Campaign-wide target按钮求助

解决Selenium无法识别Google Ads中动态加载的"Campaign-wide target"按钮问题

问题分析

你在使用Selenium下载Google Ads报表时,脚本大部分功能正常,但点击"Campaign-wide target"按钮时失败——该按钮属于动态渲染元素,只有触发下拉菜单后才会加入DOM,直接用find_element会找不到。切换iframe无效说明元素不在iframe内,核心问题是没有等待元素完全加载就执行查找操作,原代码中固定时长的sleep无法适配动态加载的延迟。

解决方案

核心思路是用Selenium显式等待替代固定sleep,等待元素满足可点击/可见条件后再操作,同时优化元素定位方式(避免绝对XPATH,提升稳定性)。

修改后的代码

from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import csv


class Bot:
    def __init__(self, user_data_dir=None, profile_dir=None, csv_filename=None):
        self.__service = ChromeService(ChromeDriverManager().install())
        self.user_data_dir = user_data_dir 
        self.profile_dir = profile_dir
        self.__options = webdriver.ChromeOptions()
        self.__options.add_argument(f"user-data-dir={self.user_data_dir}")
        self.__options.add_argument(f"--profile-directory={self.profile_dir}")
        self.csv_filename = csv_filename or "data.csv"
        self.driver = webdriver.Chrome(service=self.__service, options=self.__options)
        # 初始化显式等待对象,超时时间设为10秒
        self.wait = WebDriverWait(self.driver, 10)
 
    def login(self):
        self.driver.get("https://ads.google.com")
        
        try:
            # 等待登录按钮可见并点击
            sign_in_btn = self.wait.until(EC.element_to_be_clickable((By.XPATH, '//*[@id="header-topbar"]/div/div[3]/div/div[3]/a')))
            sign_in_btn.click()
            
        except Exception as e:
            print(e)
            # 等待抽屉按钮可见并点击
            drawer_btn = self.wait.until(EC.element_to_be_clickable((By.XPATH, '//*[@id="header-drawer"]/div/div/div/div[1]/div/button')))
            drawer_btn.click()
            # 再次等待登录按钮
            sign_in_btn = self.wait.until(EC.element_to_be_clickable((By.XPATH, '//*[@id="header-topbar"]/div/div[3]/div/div[3]/a')))
            sign_in_btn.click()

        finally:
            # 等待账号按钮可见并点击
            accnt_btn = self.wait.until(EC.element_to_be_clickable((By.XPATH, '/html/body/div[1]/root/div[2]/nav-view-loader/multiaccount-view/div/div[2]/div/div[1]/material-list/material-list-item[4]/div/div[1]')))
            accnt_btn.click()

    
    def do(self):
        self.login()
        # 等待Campaign下拉按钮可见并点击
        campaigns_drpdwn_btn = self.wait.until(EC.element_to_be_clickable((By.XPATH, '/html/body/div[2]/root/div/div[1]/div/div/div[3]/div/div/awsm-skinny-nav/nav/div[1]/div[3]/awsm-skinny-nav-item[1]/a/material-ripple')))
        campaigns_drpdwn_btn.click()

        # 等待指定Campaign按钮可见并点击
        campaign_btn = self.wait.until(EC.element_to_be_clickable((By.XPATH, '//*[@id="cmExtensionPoint-id"]/base-root/div/div[2]/div[1]/view-loader/campaign-view/tableview/div[6]/ess-table/ess-particle-table/div[1]/div/div[2]/div[3]/ess-cell[2]/campaign-name/campaign-name-generic/a')))
        campaign_btn.click()

        # 等待更多详情按钮可见并点击
        campaign_more_details_btn = self.wait.until(EC.element_to_be_clickable((By.XPATH, '/html/body/div[2]/root/div/div[1]/div/div/div[3]/div/content-header/deferred-infosnack/infosnack/div/div[1]/review-panel-trigger/button/div[2]')))
        campaign_more_details_btn.click()

        # 等待出价策略按钮可见并点击
        campaign_bid_strategy_btn = self.wait.until(EC.element_to_be_clickable((By.XPATH, "//span[contains(text(), 'Maximize conversions')]")))
        campaign_bid_strategy_btn.click()

        # 等待Campaign模拟器按钮可见并点击
        campaign_sim_btn = self.wait.until(EC.element_to_be_clickable((By.XPATH, "//span[contains(text(), 'Campaign simulator')]")))
        campaign_sim_btn.click()

        # 等待目标缩放下拉按钮可见并点击
        campaign_sim_target_dropdn = self.wait.until(EC.element_to_be_clickable((By.XPATH, "//span[contains(text(), 'Target scaling')]")))
        campaign_sim_target_dropdn.click()

        # 关键:等待"Campaign-wide target"按钮可见并点击,确保下拉菜单渲染完成
        campaign_wide_target_btn = self.wait.until(EC.element_to_be_clickable((By.XPATH, "//span[contains(text(), 'Campaign-wide target')]")))
        campaign_wide_target_btn.click()

关键优化点

  • 替换所有固定sleep为WebDriverWait显式等待,根据元素实际加载状态触发操作,避免因加载延迟导致的查找失败。
  • 初始化WebDriverWait对象统一管理超时时间,代码更简洁。
  • 对"Campaign-wide target"按钮增加等待逻辑,确保下拉菜单完全展开、元素加入DOM后再执行点击。

额外排查方向

如果上述修改仍无效,可检查以下情况:

  • 元素是否属于Shadow DOM:Google Ads部分组件可能使用Shadow DOM,需要通过driver.execute_script获取Shadow根节点后再查找元素。
  • 页面是否有隐性的加载遮罩:等待遮罩消失后再操作元素,可添加EC.invisibility_of_element_located等待遮罩隐藏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 10:25:35