如何用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
相关产品推荐
相关产品推荐

