如何获取滚动时动态更新的元素列表(Discord成员列表爬取场景)
解决Discord成员列表遍历仅能获取22个成员的方案
Discord的成员侧边栏采用虚拟滚动渲染逻辑,仅会将当前可视区域内的成员节点加载到DOM中,初始状态下只会渲染前22个左右的成员,滚动时才会动态加载后续成员、同时移除离开可视区域的旧成员,所以单次获取DOM元素只能拿到当前渲染的部分数据。
实现思路
- 先定位成员列表的可滚动父容器,而非直接获取单个成员元素
- 维护一个去重的成员存储结构,避免重复统计滚动时重复出现的成员
- 循环滚动容器,每次滚动后等待新成员加载,将新加载的成员加入存储结构,直到连续多次滚动后存储的成员数量不再变化,即代表已加载完全部成员
修改后的可运行代码
from selenium import webdriver from selenium.webdriver.common.keys import Keys from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.chrome.options import Options from selenium.webdriver import ActionChains import time # 补全options定义 o = Options() # 如有需要可以自行添加无头模式等配置 # o.add_argument("--headless=new") # 路径前加r避免转义字符报错 driver = webdriver.Chrome(r"H:\Progs\Mz's Flash\Prog\Google Chrome\chromedriver_x86_v93.exe", options=o) driver.implicitly_wait(10) driver.get("https://discord.com/channels/753059977689694218/753059977689694222") # 替换新版selenium已弃用的旧写法 email = driver.find_element(By.NAME, "email") email.send_keys('abc@example.com') password = driver.find_element(By.NAME, "password") password.send_keys('pa$$word') password.send_keys(Keys.RETURN) # 等待登录完成、页面资源加载 time.sleep(10) # 定位成员列表滚动容器,若class不匹配可自行F12查看页面元素调整选择器 member_scroll_container = WebDriverWait(driver, 30).until( EC.presence_of_element_located((By.CLASS_NAME, "members-3WRCEx")) ) # 用集合存储成员的唯一标识,避免重复统计 unique_members = set() # 记录上一次统计的成员数量,判断是否还有新成员加载 last_count = 0 # 连续无新增的次数,达到3次即判定已加载完全部成员 no_new_count = 0 while no_new_count < 3: # 获取当前已渲染的所有成员元素 current_members = driver.find_elements(By.CLASS_NAME, "clickable-1JJAn8") for member in current_members: # 用成员跳转链接作为唯一标识,也可替换为元素id等其他唯一属性 member_link = member.get_attribute("href") if member_link not in unique_members: unique_members.add(member_link) # 此处可添加你的自定义操作,比如点击、采集成员信息等 # driver.execute_script("arguments[0].scrollIntoView();", member) # member.click() # time.sleep(2) # 滚动容器到最底部 driver.execute_script("arguments[0].scrollTop = arguments[0].scrollHeight", member_scroll_container) time.sleep(2) # 等待新成员加载完成,可根据网络情况调整时长 # 判断是否有新增成员 current_count = len(unique_members) if current_count == last_count: no_new_count +=1 else: no_new_count = 0 last_count = current_count print(f"共加载到{len(unique_members)}个成员") # 后续可自行遍历unique_members执行对应业务逻辑
注意事项
- 如果运行时提示找不到滚动容器,可打开Discord页面按F12,选中成员列表的滚动区域,复制对应元素的class属性替换代码中的选择器即可
- 操作频率不要过高,Discord有反爬机制,频繁请求可能触发人机验证甚至账号封禁
- 若使用的selenium版本较低,可换回原
find_element_by_name写法,不影响核心逻辑运行
内容的提问来源于stack exchange,提问作者captain_majid
相关产品推荐
相关产品推荐

