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

如何用Python与Selectolax提取同名CSS类的多组价格数据

网页爬取问题:区分同CSS类的零售价与促销价

我在学习基础网页爬取时遇到问题:目标网站的零售价和促销价都使用price这个CSS类,目前只能提取到第一个出现的零售价,无法获取促销价。想要提取出格式为{'model': '<型号>', 'retail_price': '<xxx.xx>', 'sale_price': '<xxx.xx>'}的商品数据,求解决思路。

我已编写的代码

import httpx
from selectolax.parser import HTMLParser


url = "https://hvacdirect.com/ductless-mini-splits/single-zone-ductless-mini-splits/filter/wall-mounted/aciq.html"
headers = {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36 OPR/104.0.0.0"}

#Get page html
resp = httpx.get(url, headers=headers)
html = HTMLParser(resp.text)

#Get product list
products = html.css("div.products.wrapper.grid.products-grid ol li")
for product in products:
    item = {
        "name":product.css_first(".product-item-sku").text().strip(),
        "retail_price":product.css_first(".price").text().strip(),
    }
    print(item)

解决思路与修改代码

核心思路

因为两个价格共用price类,不能只用css_first()取第一个元素,而是要获取该商品下所有price元素,再根据位置或父容器区分零售价和促销价:

  • 用css(".price")获取当前商品下的所有价格元素列表
  • 根据元素在列表中的索引分配对应价格(通常零售价在前,促销价在后,可根据实际页面调整)
  • 处理无促销价的边界情况,避免报错

修改后的代码

import httpx
from selectolax.parser import HTMLParser

url = "https://hvacdirect.com/ductless-mini-splits/single-zone-ductless-mini-splits/filter/wall-mounted/aciq.html"
headers = {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36 OPR/104.0.0.0"}

# 获取页面HTML
resp = httpx.get(url, headers=headers)
html = HTMLParser(resp.text)

# 获取商品列表
products = html.css("div.products.wrapper.grid.products-grid ol li")
for product in products:
    # 提取型号(对应需求里的model字段)
    model = product.css_first(".product-item-sku").text().strip()
    # 获取当前商品下所有.price元素
    price_items = product.css(".price")
    
    retail_price = None
    sale_price = None
    
    if len(price_items) >= 2:
        # 假设第一个是零售价,第二个是促销价,可根据实际页面调整顺序
        retail_price = price_items[0].text().strip()
        sale_price = price_items[1].text().strip()
    elif len(price_items) == 1:
        # 无促销价时,零售价和促销价一致
        retail_price = price_items[0].text().strip()
        sale_price = retail_price
    
    item = {
        "model": model,
        "retail_price": retail_price,
        "sale_price": sale_price
    }
    print(item)

更精准的定位方式(可选)

如果页面中价格元素有父容器区分(比如零售价在old-price容器,促销价在special-price容器),可以直接通过父类定位,避免依赖索引:

# 替换价格提取部分的代码
retail_elem = product.css_first(".old-price .price")
sale_elem = product.css_first(".special-price .price")

retail_price = retail_elem.text().strip() if retail_elem else None
sale_price = sale_elem.text().strip() if sale_elem else retail_price

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 22:55:56