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

如何提升Python下载解析JSON的速度?及json.load报错排查

问题解答

一、初始代码速度慢的原因与优化方向

你的初始代码速度比Java慢10倍的核心原因,几乎可以肯定是没有启用HTTP压缩。很多Java HTTP客户端会自动添加Accept-encoding: gzip, deflate请求头,服务器会返回压缩后的内容,体积大幅减小,传输速度自然更快;但Python标准库的urlopen默认不会添加这个头,服务器返回的是未压缩的原始JSON,当JSON体积较大时,下载耗时会显著增加。

你后来添加Accept-encoding请求头的思路完全正确,这是提升速度的关键一步。

二、json.load(fp)报错的原因与解决办法

你遇到的TypeError: the JSON object must be str, not 'bytes',问题出在GzipFile的默认工作模式上:

  • GzipFile默认以二进制模式打开文件对象,它的read()方法返回的是bytes类型数据;
  • json.load()虽然支持传入文件对象,但要求该对象返回的是字符串(str),而非字节流。

这里有两种简单的解决方案:

方案1:将GzipFile以文本模式打开

修改gzip.GzipFile的初始化参数,指定mode='rt'(文本读取模式)并设置编码(比如utf-8),这样fp返回的就是字符串,json.load()就能正常解析:

def read_json_data(url_str: str):
    req = Request(url_str, headers={'Accept-encoding': 'gzip'})
    with urlopen(req) as resp:
        if resp.info().get('Content-Encoding') == 'gzip':
            with gzip.GzipFile(fileobj=resp, mode='rt', encoding='utf-8') as fp:
                data = json.load(fp)
        else:
            data = json.load(resp)
    return data

方案2:用json.loads()手动解码字节流

如果不想修改GzipFile的模式,也可以先读取字节流,解码成字符串后再用json.loads()解析:

def read_json_data(url_str: str):
    req = Request(url_str, headers={'Accept-encoding': 'gzip'})
    with urlopen(req) as resp:
        if resp.info().get('Content-Encoding') == 'gzip':
            with gzip.GzipFile(fileobj=resp) as fp:
                data_bytes = fp.read()
                data = json.loads(data_bytes.decode('utf-8'))
        else:
            data = json.load(resp)
    return data

额外补充:有些服务器可能返回deflate格式的压缩内容,你可以把请求头改成Accept-encoding: gzip, deflate,再用zlib模块对应处理deflate的情况,不过大部分场景下gzip已经能覆盖需求了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 10:06:30