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

Selenium无法实现上下滚动加载页面问题求助及代码优化

解决Selenium上下滚动加载及Chrome eager模式疑问

修改后的完整代码

import pandas as pd
from tqdm.notebook import tqdm
import random
import requests, time, json
from bs4 import BeautifulSoup, element
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
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.webdriver.common.alert import Alert

def save_pagesources(url):
    driver.get(url)
    
    # 等待弹窗按钮加载并关闭
    WebDriverWait(driver, 10).until(
        EC.element_to_be_clickable((By.XPATH, '//button[@class="Button Modal-closeButton Button--plain"]'))
    ).click()

    scrolls = 100
    while True:
        scrolls -= 1
        
        # 1. 向下滚动到中间位置
        driver.execute_script("window.scrollTo(0, 4000);")
        time.sleep(random.uniform(2, 4))  # 随机延迟模拟用户行为
        
        # 2. 向上滚动一段距离,触发加载逻辑
        driver.execute_script("window.scrollTo(0, 1000);")
        time.sleep(random.uniform(1, 3))
        
        # 3. 滚动到页面底部
        driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
        time.sleep(random.uniform(2, 4))

        # 检查是否出现"写回答"按钮,判断是否加载完成
        try:
            WebDriverWait(driver, 10).until(
                EC.presence_of_element_located((By.XPATH, '//div[@class="Card"]/a/button[contains(text(), "写回答")]'))
            )
            break
        except:
            pass

        if scrolls < 0:
            break

    html = driver.page_source
    return html


if __name__ == "__main__":
    def chromedriver_path():
        return '/usr/local/bin/chromedriver'

    chromedriver_path = chromedriver_path()
    chrome_options = Options()
    # 可选开启eager模式,根据实际测试情况决定
    # chrome_options.page_load_strategy = 'eager'
    # chrome_options.add_argument('--headless')

    driver = webdriver.Chrome(chromedriver_path, options=chrome_options)

    url_list = ['https://www.zhihu.com/question/48067420']

    for i in tqdm(range(len(url_list))):
        sleep_time = random.choice([9,2,5,4,8])
        time.sleep(sleep_time)
        html = save_pagesources(url_list[i])
        filename = f'zhihu_html/zhihu_{i}.html'
        print(filename)
        with open(filename, "w", encoding="utf-8") as file:
            file.write(html)
    driver.quit()

关键修改说明

  • 替换过时的元素定位方法:将find_element_by_xpath改为Selenium 4+推荐的find_element(By.XPATH, ...),同时增加显式等待确保弹窗按钮可点击后再操作,避免元素未加载完成导致的报错。
  • 匹配需求的滚动逻辑:严格按照「向下滚动→向上滚动→滚到底部」的流程实现,触发目标网站的加载机制;用随机延迟替代固定sleep,更贴近真实用户行为,降低反爬风险。
  • 优化代码细节:修复重复导入random的问题,简化随机等待时间的获取逻辑,让代码更简洁易读。

关于Chrome eager模式的建议

  • 开启优势:eager模式会在页面DOM树构建完成(进入交互状态)时停止等待,相比默认的normal模式(需等待所有资源加载完成),能大幅减少页面加载等待时间,提升爬虫效率。
  • 开启风险:如果页面关键初始元素(比如弹窗按钮)依赖图片、样式表等非核心资源加载完成才能显示,eager模式下可能出现元素定位失败的情况。
  • 决策建议:先测试开启eager模式后的运行情况,如果弹窗按钮能正常定位、滚动加载逻辑正常执行,就保留开启;如果出现元素未找到等错误,就关闭该模式,使用默认的normal模式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 09:55:38