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

如何用Selenium从动态URL批量采集商品公斤价与描述

iFood商品详情页公斤价与描述采集方案

需要采集iFood某店铺商品的**公斤价(Preço do quilo)**和完整描述,但店铺主页面仅显示500克这类小份量价格,必须进入商品详情页(通过主页面URL拼接&item=商品ID生成)才能获取目标数据。现有Selenium代码仅能抓取主页面信息,无法进入详情页采集,以下是修改方案:

核心修改思路

  • 提取商品ID:从主页面商品卡片的属性或链接中提取商品ID,用于构造详情页URL
  • 构造详情页链接:通过主页面URL拼接&item=商品ID直接访问详情页,比点击跳转更高效
  • 定位目标元素:在详情页中定位显示公斤价和完整描述的元素
  • 替换强制等待:用Selenium显式等待替代time.sleep,提升代码稳定性
  • 异常容错处理:增加多层异常捕获,避免单个商品或页面出错导致程序中断

修改后的完整代码

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 selenium.common.exceptions import TimeoutException, WebDriverException
import json

# 目标店铺链接列表
lista = [
    "https://www.ifood.com.br/delivery/brasilia-df/oba-hortifruti---212-sul-asa-sul/8b66f111-5766-409e-97aa-6034868aa230?corredor=4e10f079-d107-437b-b278-e71a964b444b&originArea=aisleMenu"
]

driver = webdriver.Chrome()  # 根据你的浏览器类型选择对应Driver
wait = WebDriverWait(driver, 10)  # 显式等待超时时间设置为10秒

for shop_url in lista:
    try:
        # 访问店铺主页面
        driver.get(shop_url)
        
        # 滚动加载所有商品
        scrolls = 5
        while scrolls > 0:
            driver.execute_script("window.scrollTo(0, document.body.scrollHeight)")
            # 等待页面滚动加载完成
            wait.until(lambda d: d.execute_script("return document.body.scrollHeight") > driver.execute_script("return window.pageYOffset + window.innerHeight"))
            scrolls -= 1
        
        # 最后一次滚动到底部确保所有商品加载
        driver.execute_script("window.scrollTo(0, document.body.scrollHeight)")
        wait.sleep(1)
        
        # 获取所有商品卡片元素
        items = wait.until(EC.presence_of_all_elements_located((By.CLASS_NAME, 'product-card-content')))
        
        for item in items:
            # 提取商品ID,优先从data-item-id属性获取
            item_id = None
            try:
                item_id = item.get_attribute("data-item-id")
                if not item_id:
                    # 属性不存在则从商品链接中解析
                    item_link = item.find_element(By.TAG_NAME, "a").get_attribute("href")
                    item_id = item_link.split("&item=")[-1]
            except:
                print("无法提取商品ID,跳过该商品")
                continue
            
            # 构造详情页URL
            detail_url = f"{shop_url}&item={item_id}"
            
            try:
                # 访问商品详情页
                driver.get(detail_url)
                
                # 等待详情页核心元素加载完成
                wait.until(EC.presence_of_element_located((By.CLASS_NAME, 'product-detail__description')))
                
                # 获取商品完整描述
                descricao = wait.until(EC.presence_of_element_located((By.CLASS_NAME, 'product-detail__description'))).text
                
                # 获取公斤价,兼容多种可能的元素定位
                preco_quilo = ""
                try:
                    # 优先通过文本定位公斤价元素
                    price_unit = wait.until(EC.presence_of_element_located((By.XPATH, "//*[contains(text(), 'Preço do quilo')]/following-sibling::span")))
                    preco_quilo = price_unit.text
                except:
                    try:
                        # 备用定位方式:通过class定位
                        preco_quilo = wait.until(EC.presence_of_element_located((By.CLASS_NAME, 'product-price__unit'))).text
                    except:
                        preco_quilo = "未找到公斤价"
                
                # 整理并输出数据
                item_data = {
                    'descricao': descricao,
                    'preco_quilo': preco_quilo,
                    'item_id': item_id
                }
                print(json.dumps(item_data, ensure_ascii=False))
                
                # 返回店铺主页面,继续处理下一个商品
                driver.back()
                # 等待主页面商品列表重新加载完成
                wait.until(EC.presence_of_all_elements_located((By.CLASS_NAME, 'product-card-content')))
                
            except (TimeoutException, WebDriverException) as e:
                print(f"处理商品ID {item_id} 时出错: {str(e)}")
                driver.back()
                continue
            
    except (TimeoutException, WebDriverException) as e:
        print(f"访问店铺链接 {shop_url} 时出错: {str(e)}")
    except Exception as e:
        print(f"处理店铺 {shop_url} 时发生未知错误: {str(e)}")

driver.quit()

代码说明

  • 采用WebDriverWait显式等待,确保元素加载完成后再操作,避免因页面加载慢导致的元素找不到问题
  • 兼容两种商品ID提取方式,提升适配性
  • 针对公斤价设计了双重定位逻辑,适配不同页面结构
  • 每次处理完商品后返回主页面,保证遍历流程不中断
  • 多层异常捕获,单个商品或页面出错不会导致整个程序终止

内容的提问来源于stack exchange,提问作者João Felix

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 06:23:16