如何向GasBuddy GraphQL API发请求?403报错及解码异常求助
解决GasBuddy GraphQL API 403错误及数据提取问题
问题原因
你的请求返回403 Forbidden是因为GasBuddy的API会验证请求头,拒绝非浏览器发起的请求。而JSONDecodeError是因为403响应通常是HTML错误页面而非JSON格式,导致解析失败。请求格式本身没有错误,但缺少必要的浏览器模拟头信息。
修复方案
1. 添加浏览器请求头
必须添加至少User-Agent头来模拟真实浏览器请求,还可以补充Accept、Referer等头字段提高通过率。
2. 简化GraphQL查询
只请求你需要的字段(加油站地址和普通汽油价格),减少冗余数据传输。
修正后的代码
import requests url = "https://gasbuddy.com/graphql" # 模拟浏览器请求头 headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36", "Accept": "application/json", "Referer": "https://www.gasbuddy.com/" } # 简化后的查询,仅获取所需字段 query = { "operationName": "LocationBySearchTerm", "variables": { "fuel": 1, "maxAge": 0, "search": "78015" # 替换为目标邮编 }, "query": """ query LocationBySearchTerm($fuel: Int, $maxAge: Int, $search: String) { locationBySearchTerm(search: $search) { stations(fuel: $fuel, maxAge: $maxAge) { results { address { line1 locality postalCode region } prices { fuel_product credit { price } } } } } } """ } response = requests.post(url, json=query, headers=headers) # 检查响应状态码 if response.status_code == 200: data = response.json() # 提取所需数据 stations = data['data']['locationBySearchTerm']['stations']['results'] for idx, station in enumerate(stations, 1): # 拼接完整地址 addr = station['address'] full_addr = f"{addr['line1']}, {addr['locality']}, {addr['region']} {addr['postalCode']}" # 查找普通汽油价格 regular_price = None for price_item in station['prices']: if price_item['fuel_product'] == 'regular_gas': regular_price = price_item['credit']['price'] break print(f"加油站 {idx}:") print(f"地址: {full_addr}") print(f"普通汽油价格: ${regular_price}\n") else: print(f"请求失败,状态码: {response.status_code}") print("响应内容:", response.text)
注意事项
- 如果仍然返回403,可以尝试从Chrome开发者工具中复制完整的请求头(包括Cookie字段),但Cookie可能会过期,需要定期更新。
- GasBuddy的API可能会随时调整验证规则,若出现新的错误,建议重新查看浏览器的Network请求,确保头信息和参数与浏览器一致。
内容的提问来源于stack exchange,提问作者IamTrying
相关产品推荐
相关产品推荐

