如何快速获取Steam市场求购价 解决requests返回None问题
问题描述
参考截图所示为Steam市场的求购(Request to buy)价格栏位,需要从Steam市场获取该类求购价格数值,使用requests+BeautifulSoup编写如下代码爬取时,执行后仅能得到None返回值;如果改用Selenium实现爬取,单请求耗时接近3秒,速度过慢无法满足使用需求,需要可快速获取求购价格数值的方案。

原有测试代码:
name = "P250 | Red Rock (Battle-Scarred)" html = requests.get("https://steamcommunity.com/market/listings/730/"+name).text soup = BeautifulSoup(html,"html5lib")
问题原因
- requests直接请求商品列表页拿不到求购价,核心原因是Steam市场的求购订单数据是页面初始加载完成后,通过异步接口动态拉取渲染的内容,静态HTML源码中不存在该部分数据,因此BeautifulSoup解析静态源码只能返回None。
- Selenium方案速度慢,是因为其需要加载完整页面资源、启动浏览器渲染引擎,运行开销极高,该场景下完全没有使用必要。
快速获取方案
直接调用Steam市场公开的订单查询异步接口即可,无需加载整个商品页面,单请求耗时通常在200-500ms区间,速度是Selenium方案的6-10倍。
实现逻辑
- 对饰品名称做URL编码,避免特殊字符未转义导致请求失败。
- 先请求商品静态列表页,通过正则从源码中提取对应饰品的唯一标识
item_nameid,该值存在于静态源码中,无需渲染页面。 - 携带必选参数请求订单专用接口
https://steamcommunity.com/market/itemordershistogram,接口直接返回JSON格式数据,解析其中buy_order_graph字段即可获取求购价格信息,该字段按求购价格从高到低排序,第一个值即为当前最高求购价。
接口必选参数说明:
country:国家代码,填CN即可language:语言代码,填schinese返回中文内容,填english返回英文内容currency:货币类型,填1对应美元,填23对应人民币item_nameid:提取到的饰品唯一IDtwo_factor:固定传值0即可
可直接运行的示例代码
import requests from urllib.parse import quote import re def get_steam_highest_buy_price(item_name: str, appid: int = 730, currency: int = 23): headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36" } # 编码饰品名称,请求静态商品页 encoded_name = quote(item_name) list_page_url = f"https://steamcommunity.com/market/listings/{appid}/{encoded_name}" list_resp = requests.get(list_page_url, headers=headers, timeout=10) # 正则提取item_nameid id_match = re.search(r'Market_LoadOrderSpread\(\s*(\d+)\s*\)', list_resp.text) if not id_match: raise RuntimeError("提取商品ID失败,请检查输入的饰品名称是否准确") item_nameid = id_match.group(1) # 请求订单接口 order_api_url = "https://steamcommunity.com/market/itemordershistogram" req_params = { "country": "CN", "language": "schinese", "currency": currency, "item_nameid": item_nameid, "two_factor": 0 } order_resp = requests.get(order_api_url, params=req_params, headers=headers, timeout=10) order_data = order_resp.json() # 解析最高求购价 buy_orders = order_data.get("buy_order_graph", []) if not buy_orders: return None return buy_orders[0][0] if __name__ == "__main__": test_item = "P250 | Red Rock (Battle-Scarred)" highest_price = get_steam_highest_buy_price(test_item) print(f"饰品当前最高求购价:{highest_price} 元")
优化建议
- 批量爬取时复用
requests.Session()对象,减少TCP握手开销,速度可提升30%左右。 - 控制请求频率,Steam对短时间内的高频请求会触发临时IP封禁,建议添加1-2秒的请求间隔,批量采集场景可搭配代理池使用。
- 接口返回的
buy_order_graph字段包含全档位求购单的价格、挂单数量信息,可按需提取对应内容,不止局限于最高求购价。
内容的提问来源于stack exchange,提问作者user11225404
相关产品推荐
相关产品推荐

