Python Selenium 有限加载网页滚动至页底的最优实现方法
雅虎财经历史行情页稳定滚动的实现逻辑
之前方案失效的核心原因
- 通用无限滚动方案适配错位:雅虎历史行情页的日线数据不是全局页面滚动触发懒加载,是固定高度的独立表格容器内部的滚动事件触发数据加载,全局
document.body的滚动高度从页面初始渲染后几乎不会变化,靠读取全局body高度判断加载进度的逻辑从根上就不成立。 - 元素检测逻辑失真:之前用
while driver.find_element_by_tag_name('tfoot')的判定方式存在明显问题——tfoot元素是页面初始加载就存在于DOM中的,和是否滚动到页面底端没有任何关联;加上固定2秒的硬编码等待,一旦遇到网络波动,数据加载慢于等待时间,就会提前触发终止判定,出现加载卡停的问题。 - 旧代码本身存在语法错误:第一版通用方案里的
time.sleep(2)()是把无返回值的sleep方法强行加括号调用,运行时会直接抛错中断流程。
最优可落地实现方案
整个逻辑的核心是放弃全局滚动的通用思路,完全匹配雅虎页面的滚动机制设计判定规则:
- 第一步:精准定位真实的滚动触发容器,不操作全局window滚动
法语版雅虎财经的行情表格容器的CSS选择器为div.tableContainer.yf-j5d1ld,该元素自带overflow-y: auto的可滚动属性,所有历史日线数据都在这个容器内部逐批加载,所有滚动操作都针对这个容器执行。 - 第二步:用确定性的加载状态替代固定时长等待
每次滚动后不硬编码sleep等待,而是通过两个可量化的指标判断加载进度:- 表格加载的总行数是否比上次滚动后有新增
- 页面是否出现代表数据加载完成的固定终止提示(法语站的提示文案为
Aucune donnée trouvée pour votre plage de dates)
- 第三步:设置兜底循环边界
因为该页面加载总量是由用户指定的日期区间固定的,不存在真正的无限加载,设置连续3-5次滚动没有新增数据就自动终止循环,避免死循环。
对应的可运行Selenium代码示例:
from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC # 等待行情容器加载完成 scroll_container = WebDriverWait(driver, 15).until( EC.presence_of_element_located((By.CSS_SELECTOR, "div.tableContainer.yf-j5d1ld")) ) # 加载完成的终止判定标识(法语站对应文案) end_indicator_locator = (By.XPATH, "//span[contains(text(), 'Aucune donnée trouvée pour votre plage de dates')]") max_idle_retry = 4 idle_count = 0 last_loaded_row = 0 while idle_count < max_idle_retry: # 针对内部容器执行滚动到底部操作 driver.execute_script(""" arguments[0].scrollTop = arguments[0].scrollHeight """, scroll_container) # 等待新的表格数据行加载,最长等待5秒 WebDriverWait(driver, 5).until( lambda d: len(d.find_elements(By.CSS_SELECTOR, "table tbody tr")) != last_loaded_row ) current_loaded_row = len(driver.find_elements(By.CSS_SELECTOR, "table tbody tr")) # 检测是否到达加载终点 if driver.find_elements(*end_indicator_locator): break # 累计无新增数据的空闲次数 if current_loaded_row == last_loaded_row: idle_count += 1 else: idle_count = 0 last_loaded_row = current_loaded_row
踩坑注意事项
- 弃用Selenium 3版本的老旧定位API(如
find_element_by_tag_name),统一使用By类进行元素定位,避免API版本兼容问题导致的流程中断 - 不要依赖滚动高度的瞬时值做判定:每次滚动后留足加载响应的等待时间,优先用数据行数量、终止提示这类业务层的信号判断加载进度,比纯几何尺寸的判定稳定得多
- 不需要追求一次性滚到页面最底部:雅虎的懒加载是触发式的,每次滚动到底部会加载下一批200条左右的日线数据,循环执行直到触发终止提示即可。
内容的提问来源于stack exchange,提问作者user14148145
相关产品推荐
相关产品推荐

