You need to enable JavaScript to run this app. Selenium滚动爬取JS渲染网页仅获取前8条商品数据的问题求解
优惠活动
大模型
产品
解决方案
定价
更多

Selenium滚动爬取JS渲染网页仅获取前8条商品数据的问题求解

代码调整方案

现存问题

你当前逻辑只抓到顶部8个商品,本质是几个逻辑偏差导致的:

  • 滚动高度取的参照前后不统一:初始化时拿document.documentElement.scrollHeight做基准,循环里却用document.body.scrollHeight做对比,在存在非全局滚动容器的页面上,两个值根本对不上,系统会直接判定已经滚到底,退出循环,根本不会触发后面的商品加载。
  • 滚动容器不对:这类电商站的商品列表不是挂在全局页面上滚动的,是独立的DOM容器自己带滚动条,你直接执行window.scrollTo(0, document.body.scrollHeight)根本碰不到列表的滚动区域,自然不会触发分页加载。
  • 硬等20秒的逻辑不靠谱:固定等待时长要么不够久,新商品没渲染出来就开始算高度,要么等太久浪费时间,卡不准无限滚动的触发时机。
  • 选元素用的类名带随机hash:你写的fWFKvm、fQbbTY这类后缀是前端打包时生成的随机值,每次发版就会变,就算商品正常加载了,也可能因为类名对不上抓不到。

调整方向

  • 别再靠整个页面的高度判断加载进度了,直接统计当前已经渲染出来的商品节点数量,等数量不再增长的时候,就说明所有商品都加载完了。
  • 滚动的时候直接定位到当前最后一个已加载的商品位置,把它滚到视口中间,不管列表是哪个容器承载的,都能触发对应的懒加载逻辑。
  • 把固定sleep换成显式等待,每次滚动后等新的商品节点出现,再进入下一轮循环,不用卡死等20秒。
  • 写选择器的时候别带类名末尾的随机hash,用属性包含匹配的方式,比如找带MarketplaceProductList__Wrapper前缀的元素就行,避免类名变了抓不到。

调整后的参考代码

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

url = 'https://www.faire.com/retailer/r_9vkjixqbpq/category/Beauty%20&%20Wellness/subcategory/Bath%20&%20Body?filters=sorting%3Afeatured'
wd.get(url)
# 等首个商品列表渲染出来
WebDriverWait(wd, 15).until(
    EC.presence_of_element_located((By.CSS_SELECTOR, '[class*="MarketplaceProductList__Wrapper"]'))
)

last_count = 0
wait = WebDriverWait(wd, 20)
while True:
    current_products = wd.find_elements(By.CSS_SELECTOR, '[class*="MarketplaceProductList__TileWrapper"]')
    current_count = len(current_products)
    # 连续两次数量没变化,就说明没有新商品加载了
    if current_count == last_count:
        break
    last_count = current_count
    # 滚到最后一个已加载的商品位置,触发后续分页
    wd.execute_script("arguments[0].scrollIntoView({block: 'center'});", current_products[-1])
    # 等新的商品加载出来,再进入下一轮
    wait.until(lambda d: len(d.find_elements(By.CSS_SELECTOR, '[class*="MarketplaceProductList__TileWrapper"]')) > last_count)

# 全量加载完成后再提取内容
soup = BeautifulSoup(wd.page_source, 'lxml')
listings = soup.select('div[class*="MarketplaceProductList__TileWrapper"]')
for item in listings:
    product_name = item.select_one('span[class*="FallbackHandler__ContentParentWrapper"]').get_text(strip=True)
    print(product_name)

这个逻辑绕开了“找不对滚动容器”“高度算不准”的常见坑,不管页面是全局滚动还是内部容器滚动,只要能看到最后一个商品的位置,就能触发懒加载;同时选择器不依赖随机生成的类名后缀,兼容性更强。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.07 18:06:09