使用Selenium滚动动态页面至底部时遇move target out of bounds错误
问题:Selenium滚动动态加载页面时出现"move target out of bounds"错误
尝试用Selenium将页面滚动至底部,代码能完成几次滚动,但随后抛出move target out of bounds错误。页面为动态加载,推测是该原因导致问题。
原代码如下:
try: driver.maximize_window() driver.get("https://yandex.kz/maps/") time.sleep(3) input = driver.find_element(By.XPATH, "/html[1]/body[1]/div[2]/div[2]/header[1]/div[1]/div[1]/div[1]/form[1]/div[1]/div[1]/span[1]/span[1]/input[1]") time.sleep(2) input.send_keys("Актау бар") time.sleep(2) input.send_keys(Keys.ENTER) time.sleep(3) while True: scrollbar = driver.find_element(By.CLASS_NAME, "scroll__scrollbar-thumb") action = ActionChains(driver) action.click_and_hold(on_element=scrollbar).move_by_offset(0, 300) action.perform() time.sleep(2) try: add_business_view = driver.find_element(By.CLASS_NAME, "add-business-view") break except: pass
解决方案
1. 改用JavaScript滚动(最稳定)
直接操作DOM滚动比模拟滚动条拖拽更可靠,不受滚动条元素动态变化影响。可以每次滚动到当前页面底部,同时判断是否已加载到底部。
示例代码:
from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC # ... 前面的搜索代码保持不变 ... last_height = driver.execute_script("return document.body.scrollHeight") scroll_count = 0 # 滚动到底部的循环 while True: # 执行JavaScript滚动到当前页面底部 driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") # 等待内容加载完成 WebDriverWait(driver, 3).until(lambda d: driver.execute_script("return document.body.scrollHeight") > last_height) last_height = driver.execute_script("return document.body.scrollHeight") # 检查是否到达底部元素 try: WebDriverWait(driver, 2).until(EC.presence_of_element_located((By.CLASS_NAME, "add-business-view"))) break except: # 限制最大滚动次数,防止无限循环 scroll_count +=1 if scroll_count > 20: break
2. 直接滚动到目标元素(无需循环滚动)
如果明确底部标识是add-business-view,可以等待该元素出现后,直接滚动到它的位置:
from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC # ... 前面的搜索代码保持不变 ... # 等待底部元素出现 add_business = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.CLASS_NAME, "add-business-view")) ) # 滚动到该元素位置 driver.execute_script("arguments[0].scrollIntoView();", add_business)
3. 优化原滚动条操作(处理边界)
如果一定要用滚动条拖拽,需要先计算滚动条可移动的剩余距离,避免超出边界:
# ... 前面的搜索代码保持不变 ... while True: try: scrollbar = driver.find_element(By.CLASS_NAME, "scroll__scrollbar-thumb") # 获取滚动条容器和滑块的高度 scroll_container = driver.find_element(By.CLASS_NAME, "scroll__scrollbar") container_height = scroll_container.size['height'] thumb_height = scrollbar.size['height'] # 计算可向下滚动的最大距离 max_move = container_height - thumb_height if max_move <=0: break # 移动距离取300和最大距离的较小值,避免越界 move_distance = min(300, max_move) action = ActionChains(driver) action.click_and_hold(scrollbar).move_by_offset(0, move_distance).release().perform() time.sleep(2) # 检查底部元素 driver.find_element(By.CLASS_NAME, "add-business-view") break except: pass
说明:原代码的问题在于每次固定移动300像素,但动态加载后滚动条的可移动范围会缩小,当剩余可移动距离不足300时,就会触发move target out of bounds错误。
内容的提问来源于stack exchange,提问作者MMaxPwD
相关产品推荐
相关产品推荐

