爬取Aldi网站仅返回变量名,如何获取Product.ListPrice实际渲染值
问题根源
你拿到的{{Product.ListPrice}}是Vue框架的模板插值占位符,该站点的商品数据不会直接嵌入静态HTML,而是浏览器加载页面后通过JS异步调用后端接口拉取,再动态替换到页面上。你之前用Selenium拿到的结果和requests一致,是因为没有等待JS执行完成、数据渲染完毕就提前获取了页面源码。
方案1:Selenium等待渲染完成获取动态内容
该方案不需要分析接口,直接模拟浏览器完整渲染流程,代码示例如下:
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 # 配置浏览器参数 options = webdriver.ChromeOptions() # 无头模式可后台运行,不需要弹出浏览器窗口 options.add_argument('--headless=new') options.add_argument('user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0') # 规避反爬检测 options.add_argument('--disable-blink-features=AutomationControlled') driver = webdriver.Chrome(options=options) url = 'https://groceries.aldi.ie/en-GB/drinks/beer-ciders' driver.get(url) # 等待最多10秒,直到模板占位符全部被替换为实际数据 WebDriverWait(driver, 10).until_not( EC.text_to_be_present_in_element((By.ID, 'vueSearchResults'), '{{Product.ListPrice}}') ) # 提取所有商品价格 price_elements = driver.find_elements(By.CSS_SELECTOR, '#vueSearchResults span[data-qa="product-price"]') for idx, elem in enumerate(price_elements): print(f"第{idx+1}个商品价格:{elem.text.strip()}") driver.quit()
方案2:直接调用价格接口获取数据
该方案不需要启动浏览器,爬取速度更快,直接调用你提到的calculatePrices接口即可,代码示例如下:
import requests import re import json headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0', 'Accept': 'application/json', 'Content-Type': 'application/json', 'x-aldiredirect-url': 'groceries.aldi.ie' } # 第一步:拉取商品列表页,提取所有商品ID list_url = 'https://groceries.aldi.ie/en-GB/drinks/beer-ciders' list_res = requests.get(list_url, headers=headers) # 正则匹配页面所有商品ID product_ids = list(set(re.findall(r'data-product-id="(\d+)"', list_res.text))) # 第二步:调用价格计算接口 price_api = 'https://groceries.aldi.ie/api/product/calculatePrices' # 构造请求体,StoreId为默认门店ID,可自行抓包调整为你需要的门店 payload = { "ProductIds": product_ids, "StoreId": "3211", "IsClickCollect": False } price_res = requests.post(price_api, headers=headers, data=json.dumps(payload)) price_result = price_res.json() # 遍历输出所有商品价格 for product in price_result['Products']: print(f"商品ID:{product['Id']},售价:{product['ListPrice']}")
如果需要关联商品名称和价格,可从商品列表页的静态HTML中提前提取商品ID和名称的对应关系,再和接口返回的价格数据匹配即可。
内容的提问来源于stack exchange,提问作者Oxin
相关产品推荐
相关产品推荐

