Python Selenium编写NYC DOE健康筛查自动填单脚本失效问题咨询
问题描述
我是编程初学者,目前在纽约市教育局(NYC DOE)下属学校任职,按要求需定期完成健康筛查填报,这项任务枯燥重复。我希望基于PyCharm开发环境,使用Python搭配Selenium编写表单自动填充脚本,既可以节省填报时间,也能借此练习编程技能。
我参照相同逻辑编写的脚本在Google表单上可正常运行,但在NYC DOE健康筛查官网(https://healthscreening.schools.nyc/?type=G#)运行时无法正常工作,想确认问题是出在代码编写逻辑上,还是该网站内置了反机器人防护机制。
原有代码如下:
from selenium import webdriver import time web = webdriver.Chrome(executable_path='C:/path/chromedriver.exe') #web.get('https://forms.gle/4WfVvWdZSi31f5DB9') web.get('https://healthscreening.schools.nyc/?type=G#') web.set_page_load_timeout(5) Email = "EMAILTEST@gmail.com" School = "//*[@id='guest_identity_form']/div[2]/div[14]/span/span/span[1]/div" Floor = "" LastName = "DOE" FirstName = "JOHN" first = web.find_element_by_id('guest_first_name') last = web.find_element_by_id('guest_last_name') GYbutton = web.find_element_by_id('guest_isNonDOE') school = web.find_element_by_xpath('//*[@id="guest_identity_form"]/div[2]/div[14]/span/span/span[1]/div') GYbutton.click() first.send_keys(FirstName) last.send_keys(LastName) school.click()
故障原因
- 代码API版本不兼容:你使用的
find_element_by_id、find_element_by_xpath是Selenium 3版本的旧API,Selenium 4.0及以上版本已经完全废弃该系列方法,运行时会直接抛出属性不存在的错误。 - 等待逻辑错误:设置的5秒页面加载超时时间过短,且没有针对动态渲染元素做加载判断,页面元素还没完成渲染就执行查找、点击操作,会触发元素不存在、元素不可交互的报错。
- 页面交互顺序错误:学校选择下拉框是点击
guest_isNonDOE选项后才会动态加载的表单项,你在页面初始加载阶段就提前查找该元素,此时元素要么处于隐藏状态,要么还未挂载到DOM树,点击操作自然无效。 - 该站点没有部署复杂的反机器人防护机制,不需要额外绕过验证,修正上述逻辑问题即可正常运行脚本。
修正方案
替换废弃API,使用显式等待判断元素状态后再执行交互,参考代码如下:
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 time # Selenium 4.6+版本内置驱动管理器,无需手动指定chromedriver路径 web = webdriver.Chrome() web.get('https://healthscreening.schools.nyc/?type=G#') # 配置10秒显式等待,自动判断元素加载状态 wait = WebDriverWait(web, 10) # 个人填报信息 EMAIL = "EMAILTEST@gmail.com" LAST_NAME = "DOE" FIRST_NAME = "JOHN" # 等待非DOE人员选项可点击后触发点击 non_doe_btn = wait.until(EC.element_to_be_clickable((By.ID, 'guest_isNonDOE'))) non_doe_btn.click() # 等待姓名输入框加载完成后填入内容 first_name_input = wait.until(EC.presence_of_element_located((By.ID, 'guest_first_name'))) first_name_input.send_keys(FIRST_NAME) last_name_input = wait.until(EC.presence_of_element_located((By.ID, 'guest_last_name'))) last_name_input.send_keys(LAST_NAME) # 等待学校选择下拉框可点击后展开选项 school_dropdown = wait.until(EC.element_to_be_clickable((By.XPATH, '//*[@id="guest_identity_form"]/div[2]/div[14]/span/span/span[1]/div'))) school_dropdown.click() # 后续可补充学校搜索选择、剩余字段填写、提交的逻辑 time.sleep(3) # 调试阶段临时停留看效果,正式运行可删除 web.quit()
额外提示
- 尽量避免用
time.sleep()做固定时长等待,优先使用WebDriverWait显式等待,既能减少因加载慢导致的报错,也不会浪费无意义的等待时间。 - 学校选择框是搜索型下拉组件,点击展开后需要在输入框中填入学校关键词,选中匹配到的结果才能完成填报,直接点击下拉框不会自动选中内容。
- 如果运行时提示驱动版本不匹配,直接将Selenium升级到4.6以上版本即可,不需要手动下载对应版本的chromedriver。
内容的提问来源于stack exchange,提问作者MUYINJON
相关产品推荐
相关产品推荐

