Selenium报not clickable at point错误但元素已点击后程序终止问题
问题背景
正在对https://www.fragrantica.com/search/ 站点开展爬虫开发,为降低目标数据采集难度,按照「行业>性别>国家>年份」的顺序点击页面内置筛选器设置过滤条件。目前暂未开发筛选完成后的数据爬取逻辑,计划先调试确保筛选功能稳定运行后再推进后续开发。
故障现象
程序循环遍历筛选选项执行点击操作时,抛出如下报错:
ElementClickInterceptedException: Message: element click intercepted: Element <input type="checkbox" class="ais-RefinementList-checkbox" value="Fragrances"> is not clickable at point (185, 702). Other element would receive the click: <ins id="aswift_5_anchor" style="border: none !important; height: 124px !important; width: 100% !important; margin: 0px !important; padding: 0px !important; position: relative !important; visibility: visible !important; background-color: transparent !important; display: block !important; inset: auto !important; clear: none !important; float: none !important; max-height: none !important; max-width: none !important; opacity: 1 !important; overflow: visible !important; vertical-align: baseline !important; z-index: auto !important;">...</ins> (Session info: chrome=102.0.5005.63)
实际核查页面状态发现两个反常表现:
- 报错对应的复选框已经被成功点击,程序也继续执行了性别选项的点击操作,之后无理由停止运行
- 页面状态可通过截图佐证:
当前使用的筛选逻辑代码如下:
def filter(): for industry in Industry_dict.values(): for gender in Gender_dict.values(): for country in Country_dict.values(): for year in range(1920, 2023): industry_selected = WebDriverWait(driver, 100).until(EC.element_to_be_clickable((By.XPATH, industry))) industry_selected.click() time.sleep(2) gender_selected = WebDriverWait(driver, 100).until(EC.element_to_be_clickable((By.XPATH, gender))) gender_selected.click() time.sleep(2) try: country_selected = WebDriverWait(driver, 100).until(EC.element_to_be_clickable((By.XPATH, country))) country_selected.click() time.sleep(2) except: break start = WebDriverWait(driver, 100).until(EC.element_to_be_clickable((By.XPATH, start_year_xpath))) start.click() start.send_keys(year) time.sleep(2) end = WebDriverWait(driver, 100).until(EC.element_to_be_clickable((By.XPATH, end_year_xpath))) end.click() end.send_keys(year) time.sleep(2) clear = WebDriverWait(driver, 50).until(EC.element_to_be_clickable((By.XPATH, clear_filters_button))) clear.click()
根本原因
- 点击拦截的源头是页面动态加载的Google AdSense广告:报错信息里id为
aswift_5_anchor的ins标签就是典型的广告容器,这类广告加载时机不固定,会以浮动层形式覆盖在页面内容上方。Selenium自带的element_to_be_clickable判定逻辑仅校验元素本身是否存在、可见、未禁用,不会检测元素上方是否有动态加载的遮挡层,因此当点击动作下发的瞬间广告刚好加载完成浮在筛选框上方,就会触发点击拦截异常。 - 出现「报错但复选框实际选中、还能执行后续性别点击」的现象,是因为事件触发刚好卡在临界点:点击事件的部分逻辑已经传递到下层复选框,触发了状态切换,但Selenium检测到点击最终被上层广告层接收,依然会抛出异常。
- 程序中途停止的直接原因是异常未被捕获:现有代码仅给国家选择步骤加了异常捕获,行业、性别选项的点击操作没有任何异常处理,抛出的
ElementClickInterceptedException会直接中断整个循环流程,导致程序终止。 - 现有代码还存在逻辑bug:行业、性别、国家的点击操作被放在了最内层的年份循环里,每次切换年份都会重复点击这三个筛选选项,会导致选项被反复切换选中/取消状态,逻辑完全不符合预期。
修复方案
- 前置移除广告遮挡层:页面初始加载完成后,直接通过JS移除所有广告容器元素,从根源消除遮挡,代码如下:
driver.execute_script(""" // 移除AdSense广告容器 document.querySelectorAll('ins[id^="aswift_"]').forEach(el => el.remove()); // 移除其他可能的固定浮动遮挡层 document.querySelectorAll('[class*="ad-"], [id*="ad-"], ins.adsbygoogle').forEach(el => el.remove()); """) - 替换原生点击方法:封装JS点击方法绕过遮挡检测,所有元素点击都调用该方法,不会被上层元素拦截:
def safe_click(element): driver.execute_script("arguments[0].click();", element) - 补全异常处理:所有点击、输入操作都增加重试+异常捕获逻辑,避免偶发的加载延迟、遮挡问题直接中断整个遍历流程。
- 修正循环嵌套逻辑:把行业、性别、国家的点击操作移动到对应层级循环的起始位置,不要放在最内层年份循环中重复执行,每次切换筛选维度前先清空上一次的筛选条件,避免选项状态混乱。
内容的提问来源于stack exchange,提问作者Armonia
相关产品推荐
相关产品推荐



