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
问题原因分析
最初版本失效原因
- Google表单的元素类名或DOM结构可能随版本更新变化,原代码依赖的
freebirdFormviewerViewItemsRadioOptionContainer类名可能不再对应单选按钮元素 - 定义的
options全局索引是基于旧页面的按钮数量,实际页面的按钮总数或顺序可能已改变 - 核心逻辑函数
main仅定义但未调用,代码根本没执行到单选按钮点击的步骤
- Google表单的元素类名或DOM结构可能随版本更新变化,原代码依赖的
修改后报错原因
- 硬编码了索引范围
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
相关产品推荐
相关产品推荐

