You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Selenium爬取Bershka页面遇NameError及产品统计异常求助

Bershka网站产品爬取问题解决

一、NameError: name 'sosete' is not defined 错误排查

出现这个错误的核心原因是**driver.find_elements(By.CLASS_NAME, "grid-item normal")无法获取到任何元素**,导致product是空列表,for循环根本没有执行,后续涉及sosete的逻辑自然触发变量未定义错误。具体问题点:

  • By.CLASS_NAME仅支持单个类名,不能同时传入多个类("grid-item"和"normal"是两个独立类),需改用CSS选择器.grid-item.normal定位多类元素。
  • XPATH的字符串拼接逻辑错误,你写的'//*[@id="main-content"]/div/div/div[2]/section[1]/div/ul/li["+str(z+1)+"]/div'会把"+str(z+1)+"当成字面量,无法正确替换变量,应使用f-string格式化:f'//*[@id="main-content"]/div/div/div[2]/section[1]/div/ul/li[{z+1}]/div'。
  • 隐式等待位置错误,它是全局生效的等待策略,应在初始化driver后立即设置,而非点击cookie之后。

修正后的代码片段:

import time
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains

options = webdriver.ChromeOptions()
options.add_experimental_option("detach", True)
options.add_argument("start-maximized")
webdriver_service = Service(r'C:\webdrivers\chromedriver.exe')  # 用原始字符串避免路径转义问题
driver = webdriver.Chrome(options=options, service=webdriver_service)
driver.implicitly_wait(10)  # 全局隐式等待提前设置

driver.get("https://www.bershka.com/ro/femeie/accesorii/%C8%99osete-c1010194004.html")

# 处理cookie和地区选择
cookies_bttn = driver.find_element(By.ID, "onetrust-accept-btn-handler")
cookies_bttn.click()
country_save = driver.find_element(By.CSS_SELECTOR, "#geoblocking > div > div > div.select-country-container > button.button.is-sm.confirm")
country_save.click()
hoover = ActionChains(driver)

# 改用CSS选择器定位产品元素
product = driver.find_elements(By.CSS_SELECTOR, ".grid-item.normal")
z = 0
for sosete in product:
    # 修正XPATH的变量拼接
    sth = sosete.find_element(By.XPATH, f'//*[@id="main-content"]/div/div/div[2]/section[1]/div/ul/li[{z+1}]/div')
    z += 1
    print(len(sth))

二、产品数量统计不全(仅20个,实际31个)的解决

这个问题源于Bershka列表页采用滚动加载机制,初始仅渲染20个产品,剩余产品需滚动页面至底部才会加载。需先模拟滚动加载所有产品,再进行数量统计。

修正后的统计代码:

# 滚动页面到底部,加载所有产品
def scroll_to_load_all(driver):
    last_height = driver.execute_script("return document.body.scrollHeight")
    while True:
        driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
        time.sleep(2)  # 预留加载时间
        new_height = driver.execute_script("return document.body.scrollHeight")
        if new_height == last_height:
            break
        last_height = new_height

# 先执行滚动加载
scroll_to_load_all(driver)

# 再统计产品数量
whole_product = driver.find_elements(By.CLASS_NAME, "grid-card-link")
print(f"实际产品数量:{len(whole_product)}")

# 批量点击快速购买按钮的修正(需先加载所有元素)
i = 0
# 获取所有产品图片元素
products = driver.find_elements(By.CLASS_NAME, "product-image")
for product in products:
    hoover.move_to_element(product).perform()  # 需调用perform()执行动作
    time.sleep(0.5)
    # 定位当前产品的快速购买按钮(避免定位到全局所有按钮)
    purchase_bttn = product.find_element(By.CLASS_NAME, "quick-purchase")
    purchase_bttn.click()
    time.sleep(1)
    i += 1
print(f"点击了{i}个快速购买按钮")

额外提示

  • 路径字符串建议用原始字符串(加r前缀),避免\w这类转义字符导致路径错误。
  • ActionChains的动作必须调用perform()才会执行,之前的代码未执行该方法,所以无法触发快速购买按钮显示。
  • 尽量避免使用绝对XPATH,页面结构变化时极易失效,优先选择CSS选择器或相对XPATH。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 06:15:33