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

使用Python+Selenium抓取动态网页元素:如何控制滚动启停时机?

解决Airtable动态加载元素(类名变化)的抓取方案

核心思路

针对Airtable每加载6-8个元素就更换类名的情况,我们可以通过跟踪当前元素的类名,每次滚动到当前类的最后一个元素触发加载,直到检测到新类名出现,再更新目标类继续循环,直到页面无法加载新内容为止。

实现步骤

  1. 初始化Selenium并加载目标页面,等待初始元素渲染完成。
  2. 记录初始加载元素的类名作为当前目标类。
  3. 循环执行以下操作:
    • 滚动到当前目标类的最后一个元素,触发动态加载。
    • 检查是否出现新类名的元素,若出现则更新目标类。
    • 检测页面是否到达底部(滚动后高度无变化且无新类出现),到达则终止循环。
  4. 收集所有加载完成的元素并处理。

代码示例

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time
import random

# 初始化浏览器
driver = webdriver.Chrome()
driver.get("https://airtable.com/shrKma4KotuPyD1sp/tbleDyE2p94ind1eA")
driver.maximize_window()
wait = WebDriverWait(driver, 15)

# 等待初始元素加载(替换为你观察到的初始元素公共选择器)
initial_elements = wait.until(EC.presence_of_all_elements_located(
    (By.CSS_SELECTOR, "[class^='grid-cell']")  # Airtable单元格类通常以grid-cell开头
))
current_class = initial_elements[-1].get_attribute("class")
print(f"初始目标类:{current_class}")

# 循环加载直到页面底部
while True:
    # 滚动到当前类的最后一个元素,触发加载
    try:
        current_elements = driver.find_elements(By.CSS_SELECTOR, f".{current_class.replace(' ', '.')}")
        last_element = current_elements[-1]
        driver.execute_script("arguments[0].scrollIntoView({behavior: 'smooth', block: 'end'});", last_element)
        time.sleep(random.uniform(1.5, 3))  # 随机等待,规避反爬
    except IndexError:
        # 当前类元素不存在,说明已切换,跳过
        pass

    # 检查是否出现新类名的元素(取最后3个元素验证,避免误判)
    new_class_detected = False
    all_cells = driver.find_elements(By.CSS_SELECTOR, "[class^='grid-cell']")
    if len(all_cells) > len(initial_elements):
        for elem in all_cells[-3:]:
            elem_class = elem.get_attribute("class")
            if elem_class != current_class:
                current_class = elem_class
                new_class_detected = True
                print(f"检测到新类:{current_class}")
                break

    # 检测是否到达页面底部
    prev_height = driver.execute_script("return document.body.scrollHeight")
    driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
    time.sleep(random.uniform(1.5, 3))
    new_height = driver.execute_script("return document.body.scrollHeight")
    
    if new_height == prev_height and not new_class_detected:
        print("已到达页面底部,停止加载")
        break

# 收集所有元素并处理(示例:提取文本)
all_final_cells = driver.find_elements(By.CSS_SELECTOR, "[class^='grid-cell']")
print(f"共抓取到 {len(all_final_cells)} 个元素")
for cell in all_final_cells:
    print(cell.text.strip())

driver.quit()

关键注意事项

  • 类名选择:实际使用时需通过浏览器开发者工具观察Airtable元素的类名规律,替换代码中的[class^='grid-cell']为真实的元素选择器。
  • 等待优化:time.sleep可替换为WebDriverWait等待元素数量增加,提升稳定性,比如:
    wait.until(lambda d: len(d.find_elements(By.CSS_SELECTOR, "[class^='grid-cell']")) > len(all_cells))
    
  • 反爬规避:添加随机等待时间,避免频繁触发反爬机制;必要时可添加请求头模拟真实浏览器。
  • 滚动精度:使用scrollIntoView滚动到元素位置,比直接滚动到底部更精准,确保触发对应类元素的加载。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 19:58:18