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

Selenium无法识别网页按钮:自动化调研数据爬取遇阻

解决Selenium无法定位图表分类按钮的问题

核心问题分析

你遇到的问题本质是动态元素加载未等待+定位器语法错误:点击问题下拉后,图表及分类按钮是异步渲染的,直接查找会找不到元素;同时部分定位器的写法不符合Selenium语法规范,导致定位失败。

具体修复方案

1. 强制等待动态元素加载

每次点击下拉菜单后,必须用WebDriverWait等待分类按钮加载完成,不能直接执行查找操作。

2. 修正定位器

  • 分类按钮定位:

    • 错误写法:By.CLASS_NAME, "highcharts-a11y-proxy-button highcharts-no-tooltip" → CLASS_NAME不支持多类名(空格会被识别为单个类名的一部分)
    • 错误写法:By.CSS_SELECTOR, 'button.highcharts-a11y-proxy-button highcharts-no-tooltip' → 空格代表后代元素,正确的多类名CSS选择器应该用.连接两个类
    • 正确定位方式:
      # CSS选择器(推荐)
      disagg_buttons = WebDriverWait(driver, 10).until(
          EC.presence_of_all_elements_located((By.CSS_SELECTOR, 'button.highcharts-a11y-proxy-button.highcharts-no-tooltip'))
      )
      # 或者XPATH
      disagg_buttons = WebDriverWait(driver, 10).until(
          EC.presence_of_all_elements_located((By.XPATH, "//button[contains(@class, 'highcharts-a11y-proxy-button') and contains(@class, 'highcharts-no-tooltip')]"))
      )
      
  • “View data table”定位:
    原代码用By.CLASS_NAME, "li"太宽泛,会定位到页面所有li元素,应该根据文本或更精确的父元素定位:

    view_datatable_button = WebDriverWait(driver, 10).until(
        EC.element_to_be_clickable((By.XPATH, "//li[text()='View data table']"))
    )
    

3. 避免Stale Element异常

循环操作页面时,DOM结构可能变化,导致之前获取的元素引用失效,建议每次点击下拉后重新查找分类按钮。

修改后的完整代码示例

URL = "https://secure.panoramaed.com/ride/understand/1302972/survey_results/27746568#/questions"
URL2 = "https://secure.panoramaed.com/ride/understand?auth_token=geZrUH8yRr8_Ln_C9LH3"

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

driver = webdriver.Firefox()
driver.get(URL2)
driver.get(URL)

# 等待页面加载完成
WebDriverWait(driver, 15).until(
    EC.presence_of_element_located((By.CLASS_NAME, "expandable-row"))
)

# 获取所有问题下拉按钮
questions_buttons = driver.find_elements(By.CLASS_NAME, "expandable-row")

for idx, question_button in enumerate(questions_buttons):
    # 避免重复点击已展开的菜单(可根据实际页面状态调整)
    if "expanded" not in question_button.get_attribute("class"):
        question_button.click()
    
    # 等待当前问题下的分类按钮加载完成
    WebDriverWait(driver, 10).until(
        EC.presence_of_all_elements_located((By.CSS_SELECTOR, 'button.highcharts-a11y-proxy-button.highcharts-no-tooltip'))
    )
    
    # 重新获取分类按钮,避免stale element
    disagg_buttons = driver.find_elements(By.CSS_SELECTOR, 'button.highcharts-a11y-proxy-button.highcharts-no-tooltip')
    
    for disagg_button in disagg_buttons:
        # 滚动到按钮可见位置,避免被遮挡
        driver.execute_script("arguments[0].scrollIntoView(true);", disagg_button)
        disagg_button.click()
        
        # 等待"View data table"选项加载并点击
        view_datatable_button = WebDriverWait(driver, 10).until(
            EC.element_to_be_clickable((By.XPATH, "//li[text()='View data table']"))
        )
        view_datatable_button.click()
        
        # 这里加入数据采集逻辑,比如提取表格内容
        # 等待表格加载
        table = WebDriverWait(driver, 10).until(
            EC.presence_of_element_located((By.CSS_SELECTOR, "table"))
        )
        # 提取表格数据(示例)
        rows = table.find_elements(By.TAG_NAME, "tr")
        for row in rows:
            cells = row.find_elements(By.TAG_NAME, "td")
            row_data = [cell.text for cell in cells]
            # 后续可将row_data写入CSV
            print(row_data)
        
        # 关闭数据表格弹窗(根据实际页面操作调整)
        close_button = WebDriverWait(driver, 10).until(
            EC.element_to_be_clickable((By.CSS_SELECTOR, "button.close"))
        )
        close_button.click()

driver.quit()

额外注意事项

  • 如果按钮被页面元素遮挡,用execute_script滚动到可见位置再点击
  • 部分页面可能有反爬机制,可适当加入time.sleep()(但优先用显式等待)
  • 采集数据后要记得关闭弹窗,避免影响后续操作

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 01:00:11