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

Python requests请求报JSONDecodeError的修复方法

报错根因

你遇到的JSONDecodeError本质是接口返回了空内容/非JSON格式内容,不是合法的JSON结构,直接调用.json()必然解析失败,代码里一共存在5个直接触发问题的错误:

  • 请求头里携带了if-none-match缓存校验字段,服务器匹配到缓存标识时会直接返回304无内容响应,没有任何JSON数据返回
  • 初始化了requests.Session()会话对象但全程没有使用,所有POST/GET请求都是裸调用requests,会话Cookie、上下文鉴权信息完全不保留,很容易被接口鉴权拦截返回空内容/错误页
  • 取接口返回的data字段时错误写为response("data"),属于把字典当函数调用,就算JSON解析成功这行也会抛出类型错误
  • 循环硬编码爬取1到1000页,没有做终止判断,当页码超过实际总页数时接口会返回空/错误结构,直接解析必然报错
  • 代码开头对着带%d占位符的未格式化URL直接发无效POST请求,完全没有实际作用,还可能触发接口风控
修复方案

按以下顺序调整代码即可正常抓取写入:

  1. 删掉headers里的if-none-match字段,这个字段是浏览器缓存校验用,爬虫场景携带极易拿到空响应
  2. 所有接口请求统一用你初始化的Session对象s发送,自动保留会话上下文、Cookie信息,降低被拦截概率
  3. 解析JSON前先校验响应状态码,增加异常捕获,遇到非200响应、非JSON返回时直接打印错误信息终止循环,不要硬解析
  4. 修正字段取值语法,把response("data")改为response["data"],字段提取时增加容错,避免单个联系人缺失字段导致整个程序崩溃
  5. 增加翻页终止判断:当当前页返回的data为空列表时,说明已经爬完所有数据,直接跳出循环,不需要硬跑到1000页
  6. 删除开头那段无效的、对着未格式化URL发送的POST请求
修复后完整代码
import requests

# 基础配置
base_url = "https://api-prod.grip.events/1/container/4368/search?search=&sort=name&order=asc&type_id=4907,4906,5265,4964,4904,1026,4908&page=%d"
headers = {
    'authority': 'api-prod.grip.events',
    'accept': 'application/json',
    'accept-language': 'en-gb',
    'content-type': 'application/json',
    # 已删除if-none-match缓存头
    'login-source': 'web',
    'origin': 'https://connect.money2020.com',
    'referer': 'https://connect.money2020.com/money2020europe/app/home/network/list/34589',
    'sec-ch-ua': '" Not A;Brand";v="99", "Chromium";v="101", "Google Chrome";v="101"',
    'sec-ch-ua-mobile': '?0',
    'sec-ch-ua-platform': '"Windows"',
    'sec-fetch-dest': 'empty',
    'sec-fetch-mode': 'cors',
    'sec-fetch-site': 'cross-site',
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.67 Safari/537.36',
    'x-authorization': 'a422cc2a-31fb-4b4e-a1bd-a34b561adc6c',
    'x-grip-version': 'Web/8.3.11',
}

s = requests.Session()
# 会话预置headers,不用每次请求重复传
s.headers.update(headers)

with open("list.txt", "w", encoding="utf-8") as f:
    for page in range(1, 1000):
        print(f"正在抓取第{page}页...")
        resp = s.get(base_url % page)
        # 先校验响应状态
        if resp.status_code != 200:
            print(f"请求失败,状态码:{resp.status_code},响应内容:{resp.text[:200]}")
            break
        # 捕获JSON解析异常
        try:
            resp_data = resp.json()
        except Exception as e:
            print(f"JSON解析失败,错误:{str(e)},响应内容:{resp.text[:200]}")
            break
        # 取当前页数据,为空则终止爬取
        contacts = resp_data.get("data", [])
        if not contacts:
            print("所有页面抓取完成,程序终止")
            break
        # 遍历写入,增加字段容错
        for contact in contacts:
            company_name = contact.get("company_name", "")
            job_title = contact.get("job_title", "")
            name = contact.get("name", "")
            job_industry = contact.get("job_industry", "")
            target = f"{company_name}\t{job_title}\t{name}\t{job_industry}"
            f.write(target + "\n")
            print(target)
注意事项

如果调整后依然返回解析错误,先检查x-authorization字段的token是否过期,token失效时接口会返回401/403状态码和非JSON的错误提示,替换成浏览器里最新的有效token即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 07:09:27