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

使用Selenium Python爬取动态网页时如何规避ElementClickInterceptedException错误

Selenium ElementClickInterceptedException 随机触发问题解决

问题场景

爬取网页表格时,通过Selenium循环点击下拉菜单中的赛季选项切换页面,不定期触发ElementClickInterceptedException,错误均来自season_tags[i].click()代码行,循环执行次数不稳定(有时12次,有时仅6次)。

原代码片段

for i in range(0,len(season_tags)):

    """ 
    Step 1: Get to the correct Page

    """
    #Click to open the season dropdown
    driver.find_elements(By.CLASS_NAME,'current')[1].click()
    wait = WebDriverWait(driver,10)# wait for dropdown to apear
    wait.until(EC.presence_of_element_located((By.CLASS_NAME,'current')))
    
    
    #Click to chose a season
    season_tags[i].click()

    """ 
    Step 2: Scrape the data from the page
            - Format the data into a table
    """
    #Wait for table to appear
    driver.implicitly_wait(5)

    # Find table data and split it up
    table_data = driver.find_element(By.CLASS_NAME,'tableBodyContainer').text.split('\n')

    #Extract the data
    team_names = table_data[1::3]
    num_data = table_data[2::3]

    # Put the data into a dataframe
    data = pd.DataFrame([i.split(' ')for i in num_data])
    data['Teams'] = team_names
    print(season_tags[i].text)

    #Concatenate the table data
    frames.append(data)

报错信息

ElementClickInterceptedException          Traceback (most recent call last)
Input In [203], in <cell line: 4>()
     14 driver.implicitly_wait(5)
     16 #Click to chose a season
---> 17 season_tags[i].click()
     19 """ 
     20 Step 2: Scrape the data from the page
     21         - Format the data into a table
     22 """
     23 #Wait for table to appear

File ~\Anaconda\lib\site-packages\selenium\webdriver\remote\webelement.py:88, in WebElement.click(self)
     86 def click(self) -> None:
     87     """Clicks the element."""
---> 88     self._execute(Command.CLICK_ELEMENT)

File ~\Anaconda\lib\site-packages\selenium\webdriver\remote\webelement.py:396, in WebElement._execute(self, command, params)
    394     params = {}
    395 params['id'] = self._id
---> 396 return self._parent.execute(command, params)

File ~\Anaconda\lib\site-packages\selenium\webdriver\remote\webdriver.py:429, in WebDriver.execute(self, driver_command, params)
    427 response = self.command_executor.execute(driver_command, params)
    428 if response:
---> 429     self.error_handler.check_response(response)
    430     response['value'] = self._unwrap_value(
    431         response.get('value', None))
    432     return response

File ~\Anaconda\lib\site-packages\selenium\webdriver\remote\errorhandler.py:243, in ErrorHandler.check_response(self, response)
    241         alert_text = value['alert'].get('text')
    242     raise exception_class(message, screen, stacktrace, alert_text)  # type: ignore[call-arg]  # mypy is not smart enough here
---> 243 raise exception_class(message, screen, stacktrace)

ElementClickInterceptedException: Message: element click intercepted: Element <li role="option" tabindex="0" data-option-name="..." data-option-id="210" data-option-index="5" class="">2018/19</li> is not clickable at point (245, 437). Other element would receive the click: <li role="option" tabindex="0" data-option-name="..." data-option-id="274" data-option-index="4" class="">2019/20</li>
  (Session info: chrome=106.0.5249.119)
Stacktrace:
Backtrace:

解决方案

1. 优化等待逻辑+重新定位元素

原代码复用提前获取的season_tags元素列表,页面切换后元素可能失效(StaleElementReferenceException),且等待仅判断元素存在而非可点击。修改思路:

  • 提前保存所有赛季的文本内容
  • 每次循环打开下拉菜单后,重新定位当前赛季元素
  • 等待元素可点击而非仅存在
from selenium.webdriver.support import expected_conditions as EC

# 提前获取所有赛季的文本,避免元素失效
season_tags_text = [tag.text for tag in season_tags]

for i in range(len(season_tags_text)):
    # 打开赛季下拉菜单
    dropdown = driver.find_elements(By.CLASS_NAME, 'current')[1]
    dropdown.click()
    
    wait = WebDriverWait(driver, 10)
    # 等待下拉菜单展开,且目标元素可点击
    target_season = wait.until(
        EC.element_to_be_clickable(
            (By.XPATH, f"//li[@role='option' and text()='{season_tags_text[i]}']")
        )
    )
    target_season.click()
    
    # 等待表格加载完成(替换原隐式等待)
    wait.until(EC.presence_of_element_located((By.CLASS_NAME, 'tableBodyContainer')))
    
    # 后续爬取逻辑不变
    table_data = driver.find_element(By.CLASS_NAME,'tableBodyContainer').text.split('\n')
    team_names = table_data[1::3]
    num_data = table_data[2::3]
    data = pd.DataFrame([i.split(' ')for i in num_data])
    data['Teams'] = team_names
    print(season_tags_text[i])
    frames.append(data)

2. 使用JavaScript强制点击(备选方案)

若元素因页面布局遮挡无法正常点击,可通过JS直接触发元素的点击事件,绕过页面交互拦截:

# 替换原有的 season_tags[i].click()
driver.execute_script("arguments[0].click();", season_tags[i])

注意:此方法会跳过页面的交互校验,可能导致页面状态异常,仅在方法1无效时使用。

3. 滚动元素至视口后点击

若元素不在当前视口范围内,点击时可能被其他元素遮挡,先滚动到元素位置再点击:

# 滚动到目标元素位置
driver.execute_script("arguments[0].scrollIntoView(true);", season_tags[i])
# 等待元素可点击后再点击
wait = WebDriverWait(driver, 10)
wait.until(EC.element_to_be_clickable(season_tags[i])).click()

4. 避免混用隐式等待与显式等待

原代码同时使用了WebDriverWait(显式等待)和driver.implicitly_wait(5)(隐式等待),两者混用会导致等待时间不可控,建议统一使用显式等待。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 22:01:37