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

Selenium滚动异常:爬取网页表格时滚动不稳定及元素点击失败

网页表格爬取的滚动与点击问题

问题描述

我尝试从某网站的数百个页面中爬取表格数据,目前的部分代码如下:

driver.get("link")
driver.maximize_window()
window_before = driver.window_handles[0]
driver.switch_to.window(window_before)
wait = WebDriverWait(driver, 10)
driver.execute_script("window.scrollTo(0, 350)")
games = driver.find_elements(By.XPATH, '//*[@id="schedule"]/tbody/tr')

这段代码并非每次都生效:运行10次仅有5次能成功滚动页面。我尝试改用以下代码:

for i in range(0, 2): driver.find_element(By.XPATH, '//*[@id="meta"]/div[1]/p[1]/a').send_keys(Keys.DOWN)

但问题依旧:有时能达到所需滚动量,有时无反应,有时会滚动整个页面。

此代码用于导航至需点击的首个链接,后续页面同样需要滚动,且存在相同问题。这是遍历数百页读取HTML表格的循环的一部分,即便前50次生效,也无法获取全部数据。

补充:上述代码片段后紧接着以下代码:

for idx, game in enumerate(games):

driver.find_element(By.XPATH, '/html/body/div[2]/div[6]/div[3]/div[2]/table/tbody/tr['+str(idx+1)+']/td[6]/a').click()

此时会出现“element is not clickable at point (X, Y)”错误。


问题分析与解决办法

1. 滚动失效的核心原因

直接固定滚动距离或依赖元素发送按键的方式不稳定,本质是页面加载时序不匹配——执行滚动时,目标区域元素可能未完全渲染,或动态内容(如懒加载)未加载完毕,导致滚动指令未作用在正确时机。

2. 稳定滚动的替代方案

放弃固定距离滚动,改为滚动到目标元素可见的方式,结合WebDriverWait确保元素加载完成后再操作:

# 等待目标表格加载完成
schedule_table = wait.until(EC.presence_of_element_located((By.ID, "schedule")))
# 滚动到表格区域,确保完全可见(center参数让元素居中,避免被页面头部遮挡)
driver.execute_script("arguments[0].scrollIntoView({block: 'center', behavior: 'smooth'});", schedule_table)

如果需要滚动到特定行,可针对行元素操作:

# 等待目标行加载完成后滚动到该行
target_row = wait.until(EC.presence_of_element_located((By.XPATH, '//*[@id="schedule"]/tbody/tr[1]')))
driver.execute_script("arguments[0].scrollIntoView();", target_row)

3. 解决“元素不可点击”问题

该错误常见原因:元素被遮挡、不在视口内、未完全可交互。对应解决办法:

  • 先确保元素在视口内:点击前用scrollIntoView将元素滚动到可见区域;
  • 等待元素可交互:用WebDriverWait等待元素处于可点击状态,避免直接查找后立即点击;
  • 替换绝对XPATH为相对路径:绝对路径(/html/body/...)极易因页面布局变动失效,改用相对路径更稳定。

优化后的点击代码:

from selenium.webdriver.support import expected_conditions as EC

for idx, game in enumerate(games):
    try:
        # 从当前行元素内直接查找链接,相对路径更稳定
        target_link = wait.until(EC.element_to_be_clickable((By.XPATH, './td[6]/a')), game)
        # 滚动到元素可见
        driver.execute_script("arguments[0].scrollIntoView();", target_link)
        # 优先用原生点击,若仍被遮挡则改用JS点击
        target_link.click()
        # driver.execute_script("arguments[0].click();", target_link)  # 备选方案
        
        # 处理新页面数据逻辑...
        
        # 返回原页面后,重新等待表格加载(避免页面状态异常)
        driver.switch_to.window(window_before)
        wait.until(EC.presence_of_element_located((By.ID, "schedule")))
    except Exception as e:
        print(f"处理第{idx+1}行出错: {str(e)}")
        driver.save_screenshot(f"error_{idx+1}.png")  # 保存错误截图用于排查
        continue

4. 循环爬取的稳定性优化

遍历数百页时,必须加入异常捕获机制,避免单次失败导致整个脚本中断;同时每次返回原页面后,重新等待核心元素加载,确保页面状态正常。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 20:40:29