使用Python requests获取WeatherCloud站点JSON数据返回为空如何解决
问题原因分析
- 会话对象使用错误:你通过
requests.Session()创建了会话实例s,目的是自动维护第一次访问页面生成的Cookie信息,但第二次请求/device/stats接口时直接调用了requests.get(),没有复用s实例,导致请求丢失了服务端下发的会话Cookie,校验不通过因此返回空内容。 - 冗余请求头问题:你在请求头中添加了
Content-Type: text/plain; charset=UTF-8,GET请求本身不需要携带Content-Type字段,不符合接口预期也可能导致返回异常。 - CSRF提取逻辑健壮性不足:使用
findall如果匹配不到内容会直接抛出索引异常,建议用re.search做兼容判断。
修正后的可运行代码
import re import requests device = '0838117883' BASE_URL = 'https://app.weathercloud.net' device_page_url = f"{BASE_URL}/d{device}" stats_api_url = f"{BASE_URL}/device/stats" headers = { 'Referer': device_page_url, 'User-Agent': 'Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/48.0.2564.82 Chrome/48.0.2564.82 Safari/537.36', 'Accept': 'application/json, text/javascript, */*; q=0.01', 'X-Requested-With': 'XMLHttpRequest' # 标明是AJAX请求,多数站点会校验该字段 } with requests.Session() as s: # 先访问设备页面获取Cookie和CSRF令牌 page = s.get(device_page_url, headers=headers) # 更稳妥的CSRF提取方式 csrf_match = re.search(r'WEATHERCLOUD_CSRF_TOKEN:"([^&]+)"', page.text) if not csrf_match: raise Exception("无法提取CSRF令牌,请检查页面结构是否变更") csrf_token = csrf_match.group(1) # 复用会话s发起接口请求,自动带上Cookie params = { 'code': device, 'WEATHERCLOUD_CSRF_TOKEN': csrf_token } page_stats = s.get(stats_api_url, params=params, headers=headers) # 输出结果 print("请求状态码:", page_stats.status_code) print("返回JSON数据:", page_stats.json())
额外说明
如果还是获取不到数据,可以通过浏览器F12的网络面板查看正常请求的参数,确认站点是否新增了时间范围、数据类型等必填参数,补充到params里即可。若后续站点调整了CSRF的存储位置,对应调整正则匹配规则即可。
内容的提问来源于stack exchange,提问作者charlie068
相关产品推荐
相关产品推荐

