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

GraphQL爬取Payload失效,JSONDecodeError问题排查求助

问题分析与排查建议

问题概述

通过requests.post请求https://www.printables.com/graphql/接口爬取数据时,执行response.json()触发JSONDecodeError: Expecting value: line 1 column 1 (char 0)错误,此前可用的Payload现在无法正常响应,怀疑是IP封禁或Payload过期导致。

可能原因

  • IP反爬封禁:频繁循环请求触发网站反爬机制,服务器返回非JSON格式内容(如403页面、空响应),导致JSON解析失败。
  • 请求头缺失:GraphQL接口可能要求特定请求头(如User-Agent、Referer)模拟浏览器请求,代码中未添加导致服务器拒绝返回有效JSON。
  • Payload隐性变更:虽然开发者工具中Payload结构未变,但接口可能对参数默认值、字段映射或类型要求做了细微调整,导致请求不被识别。
  • 会话权限失效:若此前依赖登录状态爬取,Cookie过期或会话失效会导致服务器返回无权限的非JSON响应。

排查步骤

  1. 查看原始响应内容
    先不要直接解析JSON,打印响应状态码和文本,明确服务器返回的内容:

    response = requests.post(url, json=payload)
    print("状态码:", response.status_code)
    print("响应内容:", response.text)
    

    如果返回403/429状态码或HTML页面,大概率是IP封禁;如果是空字符串,可能是请求被拦截。

  2. 补充浏览器请求头
    复制浏览器开发者工具中请求的User-Agent、Referer等头信息,添加到请求中:

    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",
        "Referer": "https://www.printables.com/"
    }
    response = requests.post(url, json=payload, headers=headers)
    
  3. 验证IP状态
    切换网络(如手机热点)测试请求,若能正常返回JSON,说明原IP已被封禁。

  4. 对比Payload细节
    将代码中的Payload与浏览器中复制的Payload逐行对比,检查query中的字段映射、变量名是否一致(比如代码中liked: $likedByMe与变量likedByMe是否匹配)。

  5. 测试单请求
    暂时注释循环逻辑,只发送一次请求,排除因循环频繁请求导致的封禁。

优化建议

  • 添加请求延迟:循环中加入time.sleep(2),降低请求频率,避免触发反爬:
    import time
    # ...
    while True:
        # 请求逻辑...
        time.sleep(2)
    
  • 异常捕获与处理:在代码中添加异常处理,方便定位问题:
    import json
    import requests
    import time
    
    # ... 定义url、payload、headers ...
    
    cnt = 0
    id_list = []  # 避免使用关键字id作为变量名
    
    while True:
        try:
            response = requests.post(url, json=payload, headers=headers)
            response.raise_for_status()  # 抛出HTTP错误
            data = response.json()
        except requests.exceptions.HTTPError as e:
            print(f"HTTP错误: {e}, 响应内容: {response.text}")
            break
        except json.JSONDecodeError as e:
            print(f"JSON解析失败: {e}, 响应内容: {response.text}")
            break
    
        for item in data["data"]["morePrints"]["items"]:
            cnt += 1
            id_list.append(item["id"])
    
        cursor = data["data"]["morePrints"]["cursor"]
        if not cursor:
            break
        payload["variables"]["cursor"] = cursor
        time.sleep(2)
    
    ID = [int(x) for x in id_list]
    
  • 使用代理IP:若IP被封禁,可通过代理轮换IP避免限制。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 03:35:27