使用Selenium与Python爬取Aliexpress时产品列表lazyloading不加载问题排查
速卖通爬取无输出问题原因
- 传参逻辑错误:调用
get_url函数时传入了字符串字面量'search_term',而非之前通过输入获取的变量search_term,导致实际生成的搜索URL关键词完全不符合预期 - 工具混用逻辑错位:已经通过Selenium启动浏览器加载动态渲染后的页面,后续却重新使用
requests发起独立的静态请求获取页面源码,此时拿到的HTML是未执行JS、未触发懒加载的初始静态文件,不存在任何产品相关的DOM节点 - 懒加载触发逻辑失效:仅执行一次全页滚动+固定等待2秒的操作,无法匹配速卖通的懒加载规则——速卖通仅当滚动条距离当前可视区底部剩余一定距离时,才会触发下一批产品的加载,单次滚到页面底部不会直接加载全量内容
- 元素定位规则过时:使用的产品卡片类名
list product-card是旧版页面的匹配规则,当前搜索页的DOM结构已调整,无法匹配到任何元素
修正落地步骤
- 放弃
requests与Selenium混用的爬取逻辑,直接基于Selenium渲染后的浏览器DOM提取内容,避免请求状态不同步的问题 - 改写滚动触发逻辑:循环分步滚动页面,每次滚动固定距离,直到连续两次获取到的页面高度无变化,代表全量产品已加载完成
- 增加显式等待逻辑,替代固定时长的
sleep,等首批产品元素出现后再开始执行提取流程,兼顾稳定性与效率 - 替换为当前可用的元素定位规则,用类名模糊匹配的方式适配速卖通后续的小范围DOM调整
参考修正代码
""" HOT PRODUCT FINDER 输入关键词自动生成搜索URL,提取产品名、主图、链接、销量、价格,导出为Excel """ import csv from bs4 import BeautifulSoup 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 # 启动Chrome驱动 driver = webdriver.Chrome() # 最大化窗口减少响应式适配问题 driver.maximize_window() # 获取用户输入的搜索关键词 search_term = input('Keywords: ') # URL生成函数 def get_url(search_term): """根据输入关键词生成速卖通批发搜索链接""" url_template = 'https://www.aliexpress.com/wholesale?trafficChannel=main&d=y&CatId=0&SearchText={}<ype=wholesale&SortType=default&g=n' formatted_term = search_term.replace(" ", "+") return url_template.format(formatted_term) # 加载目标URL,注意这里传入的是变量search_term,不是字符串 url = get_url(search_term) driver.get(url) # 等待首批产品卡片元素加载完成,最长等待10秒 try: WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.CSS_SELECTOR, 'div[class*="product-card"]')) ) except: print("页面加载超时,请检查网络或URL是否正确") driver.quit() exit() # 循环滚动加载全量页面内容 last_height = driver.execute_script("return document.body.scrollHeight") while True: # 每次滚动当前可视区高度的2/3,匹配懒加载触发阈值 driver.execute_script("window.scrollBy(0, window.innerHeight * 2/3);") # 等待懒加载内容渲染 time.sleep(1.5) # 计算滚动后的页面总高度 new_height = driver.execute_script("return document.body.scrollHeight") # 高度无变化则代表全量加载完成,退出循环 if new_height == last_height: break last_height = new_height # 从Selenium渲染后的DOM中提取内容,不再单独发requests请求 soup = BeautifulSoup(driver.page_source, 'lxml') # 用模糊类名匹配产品卡片,适配页面类名随机后缀调整 productlist = soup.find_all('div', class_=lambda c: c and 'product-card' in c) print(f"共提取到{len(productlist)}个产品") # 后续可遍历productlist逐个提取产品名、价格、销量等字段,导出为csv/excel # driver.quit()
内容的提问来源于stack exchange,提问作者lone_coder
相关产品推荐
相关产品推荐

