使用Selenium无法获取完整数据:页面403条链接仅抓取到68条
问题分析与解决方案
你的问题核心出在滚动目标错误和等待策略不合理:
- Ocado的商品列表是在专属滚动容器内加载,而非整个页面body,直接滚动body无法触发全部商品的懒加载逻辑。
- 固定50秒的sleep既低效又不可靠,可能出现加载未完成就停止等待,或无意义浪费时间的情况。
- 仅通过页面滚动高度判断是否到底,容易被页面底部的其他静态元素干扰,导致循环提前终止。
修改后的代码
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.support import expected_conditions as EC url='https://www.ocado.com/search?entry=frozen' PATH="C:\Program Files (x86)\chromedriver.exe" driver = webdriver.Chrome(PATH) driver.get(url) # 目标商品总数 target_item_count = 403 # 定位商品列表的滚动容器 scroll_container = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.XPATH, "//div[@data-testid='search-results-container']")) ) while True: # 获取当前已加载的商品数量 current_items = driver.find_elements(By.XPATH, "//div[@class='fop-contentWrapper']") if len(current_items) >= target_item_count: break # 滚动容器到底部,触发懒加载 driver.execute_script("arguments[0].scrollTop = arguments[0].scrollHeight", scroll_container) # 显式等待新商品加载完成 try: WebDriverWait(driver, 15).until( lambda d: len(d.find_elements(By.XPATH, "//div[@class='fop-contentWrapper']")) > len(current_items) ) except: # 超时后确认是否真的无法加载更多,避免无限循环 if len(driver.find_elements(By.XPATH, "//div[@class='fop-contentWrapper']")) == len(current_items): break # 抓取所有商品链接 all_items = driver.find_elements(By.XPATH, "//div[@class='fop-contentWrapper']") for item in all_items: link = item.find_element(By.XPATH, ".//a[starts-with(@href, '/products')]").get_attribute("href") print(link) driver.quit()
关键改动说明
- 精准滚动容器:定位商品列表的专属滚动容器(
data-testid='search-results-container'),滚动这个容器才能正确触发懒加载。 - 基于商品数量的终止逻辑:直接以目标商品数作为循环终止条件,比滚动高度判断更准确。
- 智能等待机制:用显式等待替代固定sleep,等待商品数量增加后再继续滚动,确保新内容完全加载。
- 防无限循环处理:超时后检查商品数量是否不再变化,避免因页面加载异常导致死循环。
另外,若仍无法抓取全部商品,可检查是否存在登录限制——部分电商网站会限制未登录用户的加载数量,尝试登录后再执行抓取。
内容的提问来源于stack exchange,提问作者developer
相关产品推荐
相关产品推荐

