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

使用Puppeteer获取Steam游戏捆绑包价格返回null的技术求助

问题分析与解决:Puppeteer获取Steam捆绑包标题价格异常

问题现象

爬取Steam游戏(AppID 271590)的捆绑包信息时,遇到两个异常:

  1. 使用bundle.querySelector("div.discount_final_price")获取价格时,返回null
  2. 换成document.querySelector("div.discount_final_price")后,能拿到价格,但所有捆绑包价格完全重复

问题根源

  1. 标题选择器错误:遍历每个.game_area_purchase_game(捆绑包容器)时,用bundle.querySelector('div.game_area_purchase_game > h1')相当于在当前容器里再找子级的.game_area_purchase_game元素,不符合Steam实际DOM结构。
  2. 价格选择器范围与兼容性问题:
    • Steam捆绑包的价格元素分两种:有折扣时用.discount_final_price,无折扣时用.game_purchase_price,原代码只处理了一种情况
    • 原价格选择器未正确定位到当前捆绑包容器内的元素,导致返回null;全局document.querySelector只会取页面第一个匹配的价格,所以所有条目重复。

修正后的代码

import puppeteer from "puppeteer";

async function handleAgeRestriction(p) {
  await p.evaluate(() => {
    const select = document.querySelector("#ageYear");
    const selectedOption = [...select.options].find(opt => opt.text === "1900");
    selectedOption.selected = true;
  });
  await p.click("#view_product_page_btn");
}

async function getDataFromGame() {
  const browser = await puppeteer.launch({ headless: false });
  const page = await browser.newPage();

  await page.goto("https://store.steampowered.com/app/271590/");
  await handleAgeRestriction(page);

  // 等待捆绑包容器加载完成,确保页面渲染完毕
  await page.waitForSelector(".game_area_purchase_game");

  const result = await page.evaluate(() => {
    const bundles = document.querySelectorAll('.game_area_purchase_game');
    return [...bundles].map(bundle => {
      // 直接在当前捆绑包容器内获取标题
      const bundleTitle = bundle.querySelector('h1').innerText.trim();
      
      // 兼容折扣价和原价两种情况,优先取折扣价
      const discountPrice = bundle.querySelector("div.discount_final_price");
      const originalPrice = bundle.querySelector("div.game_purchase_price");
      const bundlePrice = discountPrice ? discountPrice.innerText.trim() : originalPrice.innerText.trim();

      return {
        bundleTitle,
        bundlePrice
      };
    });
  });

  console.log(result);
  await browser.close();
}

getDataFromGame();

关键修正点

  • 标题选择器:将div.game_area_purchase_game > h1改为h1,直接在当前捆绑包容器内查找标题元素
  • 价格选择器:
    • 增加兼容性判断,同时处理有折扣和无折扣的价格展示逻辑
    • 确保在当前捆绑包容器范围内查找价格元素,避免全局查找导致的重复值
  • 等待逻辑优化:只等待核心的捆绑包容器元素加载,减少冗余等待项,保证数据提取时机正确

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 01:14:51