使用Puppeteer获取Steam游戏捆绑包价格返回null的技术求助
问题分析与解决:Puppeteer获取Steam捆绑包标题价格异常
问题现象
爬取Steam游戏(AppID 271590)的捆绑包信息时,遇到两个异常:
- 使用
bundle.querySelector("div.discount_final_price")获取价格时,返回null - 换成
document.querySelector("div.discount_final_price")后,能拿到价格,但所有捆绑包价格完全重复
问题根源
- 标题选择器错误:遍历每个
.game_area_purchase_game(捆绑包容器)时,用bundle.querySelector('div.game_area_purchase_game > h1')相当于在当前容器里再找子级的.game_area_purchase_game元素,不符合Steam实际DOM结构。 - 价格选择器范围与兼容性问题:
- Steam捆绑包的价格元素分两种:有折扣时用
.discount_final_price,无折扣时用.game_purchase_price,原代码只处理了一种情况 - 原价格选择器未正确定位到当前捆绑包容器内的元素,导致返回
null;全局document.querySelector只会取页面第一个匹配的价格,所以所有条目重复。
- Steam捆绑包的价格元素分两种:有折扣时用
修正后的代码
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
相关产品推荐
相关产品推荐

