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

Python Selenium:网页爬取时如何终止滚动到div底部的while循环

Selenium滚动可滚动Div到底部时终止循环的解决方案

问题分析

现有代码的终止条件逻辑存在错误:scrollTop 设置为 scrollHeight 后,实际最大值是 scrollHeight - clientHeight,因此原条件永远无法触发。此外仅单次滚动后判断高度不够可靠,页面加载新数据需要时间,需多次验证高度是否不再变化来确认已到底部。

修改后的代码

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException
import time
import pandas as pd

def get_name_check(restaurant):
    # 此处替换为你实际的餐厅名称提取逻辑
    return restaurant.find_element(By.CLASS_NAME, '对应的名称类').text

try:
    # 定位可滚动的结果div
    scrollable_main_div = WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((By.XPATH, '//div[@aria-label="نتائج عن restaurants in riyadh"]'))
    )
    
    restaurant_names = []
    # 记录滚动前的div总高度
    last_height = driver.execute_script('return arguments[0].scrollHeight', scrollable_main_div)
    # 连续未更新高度的次数,避免加载延迟误判
    no_change_count = 0
    max_no_change = 3  # 连续3次高度不变则判定为到底部

    while True:
        # 滚动到当前div底部
        driver.execute_script('arguments[0].scrollTop = arguments[0].scrollHeight', scrollable_main_div)
        time.sleep(2)  # 等待新数据加载完成

        # 批量获取当前所有餐厅元素
        restaurants = scrollable_main_div.find_elements(By.XPATH, './/div[contains(@class,"Nv2PK THOPZb CpccDe ")]')
        
        # 遍历未收集过的餐厅元素
        for restaurant in restaurants[len(restaurant_names):]:
            name = get_name_check(restaurant)
            if name not in restaurant_names:
                restaurant_names.append(name)
                print(name)
                print("_____________________________")
        
        # 获取滚动后的div总高度
        current_height = driver.execute_script('return arguments[0].scrollHeight', scrollable_main_div)
        
        # 判断是否已到底部
        if current_height == last_height:
            no_change_count += 1
            if no_change_count >= max_no_change:
                print("已滚动到div底部,无更多数据")
                break
        else:
            no_change_count = 0
            last_height = current_height
        
        time.sleep(1)

except TimeoutException:
    print("超时异常:检查页面或调整等待时间")
except Exception as e:
    print(f"发生错误:{e}")

# 生成DataFrame并保存为CSV(添加列名与UTF-8编码避免中文乱码)
df = pd.DataFrame(restaurant_names, columns=["餐厅名称"])
df.to_csv("names.csv", index=False, encoding="utf-8-sig")

核心优化点

  • 可靠的底部判断:通过对比滚动前后的scrollHeight,连续多次高度不变则判定为无新数据,解决加载延迟导致的误判问题。
  • 批量元素处理:使用find_elements一次性获取所有餐厅元素,从已收集数量开始遍历,避免单元素定位失败的异常,同时减少重复定位开销。
  • CSV优化:添加列名并指定UTF-8编码,避免中文保存时出现乱码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 21:08:40