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

Python+Selenium操作Google Form单选按钮:随机点击失效与索引异常

问题排查:Google表单Selenium单选按钮点击失效及索引越界错误

我是编程爱好者,为自动化在线调研获取受访者,参考旧代码并将Selenium升级至最新格式后,Section_One模块的单选按钮随机点击功能完全失效。尝试修改代码后又出现索引越界错误,具体情况如下:

最初失效的代码

from selenium import webdriver
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 time
import random

#heart of the code
driver = webdriver.Chrome(r"C:\Users\User\Desktop\Python_Projects\googleForm_project\chromedriver.exe")
driver.get("https://forms.gle/JihUB5WZMsFzJrA46")
time.sleep(2)

#pagetwo
pagetwo = driver.find_element(By.XPATH, '//*[@id="mG61Hd"]/div[2]/div/div[3]/div/div[1]/div/span/span')
pagetwo.click()
time.sleep(2)

#pagethree
pagethree = driver.find_element(By.XPATH, '//*[@id="mG61Hd"]/div[2]/div/div[3]/div/div[1]/div[2]/span/span')
pagethree.click()
time.sleep(2)

declaration = driver.find_element(By.XPATH, '//*[@id="mG61Hd"]/div[2]/div/div[2]/div[2]/div/div/div[2]/div[1]/div/label/div')
declaration.click()

#pagefour
pagefour = driver.find_element(By.XPATH, '//*[@id="mG61Hd"]/div[2]/div/div[3]/div/div[1]/div[2]/span/span')
pagefour.click()
time.sleep(2)

screening_question = driver.find_element(By.XPATH, '//*[@id="i5"]/div[3]/div')
screening_question.click()

#pagefive
pagefive = driver.find_element(By.XPATH, '//*[@id="mG61Hd"]/div[2]/div/div[3]/div/div[1]/div[2]/span/span')
pagefive.click()
time.sleep(2)

#section_one

#purposely left (7) & (8) because I don't want the code to choose it
time.sleep(1)
options = [
    [0, 1], #gender
    [2, 3, 4, 5, 6], #age
    [9, 10, 11, 12], #education_lvl
    [13, 14, 15, 16], #work_exp
    [17, 18], #job_sector
    [19, 20, 21, 22, 23, 24, 25, 26], #occupation
    [27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38] #industry
]

#section_one loop
def main(counter):
    count = counter + 1

    #collect all buttons on page and submit button

    #buttons = driver.find_elements(By.XPATH, '//*[@id="i115"]/div[3]/div')
    buttons = driver.find_elements(By.XPATH, "//*[@class='freebirdFormviewerViewItemsRadioOptionContainer']")
    #buttons = driver.find_elements(By.CLASS_NAME, "appsMaterialWizToggleRadiogroupElContainer")

    for i in range(len(options)):
        buttons[random.choice(options[i])].click()

修改后报错的代码

from selenium import webdriver
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 time
import random

#heart of the code
driver = webdriver.Chrome(r"C:\Users\User\Desktop\Python_Projects\googleForm_project\chromedriver.exe")
driver.get("https://forms.gle/JihUB5WZMsFzJrA46")
time.sleep(2)

#pagetwo
pagetwo = driver.find_element(By.XPATH, '//*[@id="mG61Hd"]/div[2]/div/div[3]/div/div[1]/div/span/span')
pagetwo.click()
time.sleep(2)

#pagethree
pagethree = driver.find_element(By.XPATH, '//*[@id="mG61Hd"]/div[2]/div/div[3]/div/div[1]/div[2]/span/span')
pagethree.click()
time.sleep(2)

declaration = driver.find_element(By.XPATH, '//*[@id="mG61Hd"]/div[2]/div/div[2]/div[2]/div/div/div[2]/div[1]/div/label/div')
declaration.click()

#pagefour
pagefour = driver.find_element(By.XPATH, '//*[@id="mG61Hd"]/div[2]/div/div[3]/div/div[1]/div[2]/span/span')
pagefour.click()
time.sleep(2)

screening_question = driver.find_element(By.XPATH, '//*[@id="i5"]/div[3]/div')
screening_question.click()

#pagefive
pagefive = driver.find_element(By.XPATH, '//*[@id="mG61Hd"]/div[2]/div/div[3]/div/div[1]/div[2]/span/span')
pagefive.click()
time.sleep(2)

#section_one

a = random.randint(0, 38)
button_range = random.randint(0, 37)

radio_buttons = driver.find_elements(By.CLASS_NAME, "appsMaterialWizToggleRadiogroupElContainer")
radio_buttons[button_range].click()

    #buttons = driver.find_elements(By.XPATH, '//*[@id="i115"]/div[3]/div')
    #buttons = driver.find_elements(By.XPATH, "//*[@class='freebirdFormviewerViewItemsRadioOptionContainer']")
    #buttons = driver.find_elements(By.CLASS_NAME, "appsMaterialWizToggleRadiogroupElContainer")

报错信息

line 46, in <module>
    radio_buttons[button_range].click()
IndexError: list index out of range

问题原因分析

  1. 最初版本失效原因

    • Google表单的元素类名或DOM结构可能随版本更新变化,原代码依赖的freebirdFormviewerViewItemsRadioOptionContainer类名可能不再对应单选按钮元素
    • 定义的options全局索引是基于旧页面的按钮数量,实际页面的按钮总数或顺序可能已改变
    • 核心逻辑函数main仅定义但未调用,代码根本没执行到单选按钮点击的步骤
  2. 修改后报错原因

    • 硬编码了索引范围random.randint(0,37),但实际通过appsMaterialWizToggleRadiogroupElContainer获取到的单选按钮列表长度小于38,导致索引超出列表边界
    • 使用time.sleep()固定等待,可能页面未完全渲染就获取元素,导致列表为空或长度不足

解决方案

修复要点

  • 用显式等待替代固定休眠,确保元素加载完成后再操作
  • 按表单问题分组定位单选按钮,避免依赖全局索引
  • 基于实际获取的元素列表长度生成随机索引,杜绝越界
  • 确保核心逻辑被正确调用

完整修复代码

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
import random

# 初始化浏览器
driver = webdriver.Chrome(r"C:\Users\User\Desktop\Python_Projects\googleForm_project\chromedriver.exe")
driver.get("https://forms.gle/JihUB5WZMsFzJrA46")
wait = WebDriverWait(driver, 10)

# 页面跳转及前置操作
# 跳转到第二页
wait.until(EC.element_to_be_clickable((By.XPATH, '//*[@id="mG61Hd"]/div[2]/div/div[3]/div/div[1]/div/span/span'))).click()
# 跳转到第三页
wait.until(EC.element_to_be_clickable((By.XPATH, '//*[@id="mG61Hd"]/div[2]/div/div[3]/div/div[1]/div[2]/span/span'))).click()
# 勾选声明
wait.until(EC.element_to_be_clickable((By.XPATH, '//*[@id="mG61Hd"]/div[2]/div/div[2]/div[2]/div/div/div[2]/div[1]/div/label/div'))).click()
# 跳转到第四页
wait.until(EC.element_to_be_clickable((By.XPATH, '//*[@id="mG61Hd"]/div[2]/div/div[3]/div/div[1]/div[2]/span/span'))).click()
# 回答筛选问题
wait.until(EC.element_to_be_clickable((By.XPATH, '//*[@id="i5"]/div[3]/div'))).click()
# 跳转到第五页(Section_One所在页)
wait.until(EC.element_to_be_clickable((By.XPATH, '//*[@id="mG61Hd"]/div[2]/div/div[3]/div/div[1]/div[2]/span/span'))).click()

# Section_One 处理:按问题分组选择随机选项
def fill_section_one():
    # 定位所有单选问题组(每个问题对应一个选项组)
    question_groups = wait.until(EC.presence_of_all_elements_located((By.CLASS_NAME, "freebirdFormviewerViewItemsRadioGroup")))
    
    # 每个问题组对应的可选项索引范围(跳过不想选的选项)
    # 顺序对应:性别、年龄、教育水平、工作经验、行业领域、职业、产业
    allowed_indexes = [
        [0,1],
        [0,1,2,3,4],  # 对应原代码跳过的选项,只取前5个有效选项
        [0,1,2,3],
        [0,1,2,3],
        [0,1],
        [0,1,2,3,4,5,6,7],
        [0,1,2,3,4,5,6,7,8,9,10,11]
    ]
    
    for group, allowed in zip(question_groups, allowed_indexes):
        # 获取当前问题组的所有选项
        options = group.find_elements(By.CLASS_NAME, "freebirdFormviewerViewItemsRadioOptionContainer")
        # 随机选择允许的索引对应的选项
        random_option = options[random.choice(allowed)]
        random_option.click()

# 执行Section_One填充逻辑
fill_section_one()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 09:15:32