如何使用Selenium抓取无跳转动态加载分页的页面内容?
问题核心原因
重复抓取第一页内容的根本原因是:仅在首次进入页面时执行了一次BeautifulSoup(driver.page_source, 'html.parser')生成解析对象,后续点击下一页触发动态内容更新后,没有重新获取浏览器实时的DOM源码,循环内的商品解析逻辑一直复用第一次生成的旧soup对象,自然只能拿到第一页的数据。
除此之外现有代码还有两个容易导致爬取异常的隐患:
- 用固定时长的
time.sleep()等待不可靠,网络差、站点响应慢的时候内容还没加载完就开始解析,会漏数据;网络好的时候白等固定时长,爬取效率低 - 提前缓存的
button_NextPage元素在页面DOM动态刷新后会变成失效引用,点击时很容易抛出StaleElementReferenceException异常
修复步骤
- 把页面源码获取、soup生成、商品解析的逻辑全部放到翻页循环内部,每次页面内容更新后重新拉取最新DOM
- 替换固定sleep为Selenium的显式等待,明确等待新一页的商品内容渲染完成后再执行解析,不要靠猜等待时长
- 每次点击下一页前重新定位按钮元素,避免DOM更新导致的元素引用失效
修正后参考代码
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 from bs4 import BeautifulSoup import time import random # 初始化driver,按需补充无头模式、反检测参数等配置 driver = webdriver.Chrome() wait = WebDriverWait(driver, 10) # 最长等待10秒,轮询检查元素状态 driver.get("https://www.my-website.com/search/results-34y1i") # 首次加载等待商品区域渲染完成 wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '.product-item'))) # 替换为你实际计算得到的总页数逻辑 totalPages = 10 currentPage = 0 while currentPage < totalPages: # 每次循环都重新获取最新页面源码,生成新的soup解析对象 soup = BeautifulSoup(driver.page_source, 'html.parser') # 编写对应商品解析逻辑,基于新生成的soup提取目标字段 products = soup.select('.product-item') for product in products: # 提取商品名称、价格、链接等信息的逻辑 pass currentPage += 1 if currentPage == totalPages: break # 最后一页无需点击下一页,直接跳出 # 每次点击前重新定位下一页按钮,避免DOM更新导致元素引用失效 next_btn = wait.until(EC.element_to_be_clickable((By.ID, 'nextButton'))) next_btn.click() # 等待翻页完成:判断条件按需调整,核心是确认新内容已经渲染 # 示例逻辑:先等旧页面的第一个商品从DOM消失,确认翻页动作生效,再等新一页商品全部加载 wait.until(EC.staleness_of(products[0])) wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, '.product-item'))) # 按需加随机延时降低反爬触发概率,不要固定等太久 time.sleep(random.uniform(0.5, 1.5)) driver.quit()
额外注意事项
- 显式等待的判断条件不要直接照搬示例,要根据目标站点实际结构调整:如果站点翻页是追加商品(不是替换原有内容),就判断商品总数量增加到对应值;如果是替换式加载,就判断当前页码高亮标识更新到对应页数
- 如果站点反爬校验严格,不要连续快速点击翻页,随机延时可以适当拉长,同时配合浏览器反检测参数使用
- 局部刷新的动态站点不要用等待整页加载完成的判断逻辑,必须针对商品区域的内容变化做等待校验,否则很容易抓到半加载的残缺数据
内容的提问来源于stack exchange,提问作者small_potato
相关产品推荐
相关产品推荐

