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

http.client调用时如何分块解压Gzip编码的响应数据

报错根因
  • 你每次读取的20字节是完整gzip压缩流的截断片段,不是独立的合法gzip数据段。gzip本身有固定的文件头、校验尾、连续压缩块结构,单独把截断的小片段传给gzip.decompress()会直接触发格式识别错误,也就是你看到的not a gzipped file报错。
  • 代码存在逻辑错误:解压操作后你调用json.loads(chunk)传入的是未解压的原始压缩块,就算解压步骤正常,这行也会抛出JSON解析错误。
实现方案

不需要手动拆分原始压缩块做解压,直接用标准库gzip.GzipFile包装响应流即可,它会内部维护解压缓冲区,自动处理跨块的gzip格式校验、拼接逻辑,全程边读边解压,不会把全量响应加载到内存,符合你的要求。
注意如果你的请求头里没有声明接收gzip编码,需要补上对应头,避免服务端返回未压缩内容导致解析失败。

import http.client
import ssl
import gzip
import json

connection = http.client.HTTPSConnection(api, context=ssl._create_unverified_context())
# 补全gzip编码声明
request_headers = auth.copy()
if "Accept-Encoding" not in request_headers:
    request_headers["Accept-Encoding"] = "gzip"
connection.request('GET', api_url, headers=request_headers)
response = connection.getresponse()

# 流式包装gzip流
with gzip.GzipFile(fileobj=response) as decompressed_stream:
    # 场景1:接口返回逐行分隔的JSON(NDJSON流、日志类流式接口),直接逐行解析,内存占用极低
    for raw_line in decompressed_stream:
        raw_line = raw_line.strip()
        if not raw_line:
            continue
        parsed_data = json.loads(raw_line)
        print(parsed_data)

    # 场景2:如果是单个超大JSON对象,按固定大小读取解压后的内容
    # 注意:单块内容是JSON片段,不能直接json.loads,需要自行拼接或搭配流式JSON解析器处理
    # while chunk := decompressed_stream.read(64 * 1024): # 每次读取64KB解压后内容,可按需调整块大小
    #     # 自定义处理解压后的字节块
    #     print(len(chunk))

注意事项

  • 禁止直接对原始响应的截断压缩块调用gzip.decompress(),该方法仅支持传入完整的gzip压缩字节串,无法处理流片段。
  • 如果返回的是单个完整大JSON,逐块读取得到的是不完整的JSON片段,直接调用json.loads()会报错,需要根据接口返回的格式选择逐行解析、全量拼接或流式JSON解析方案。
  • 整个流程全程流式读写,不会将全量压缩内容、解压内容一次性加载到内存,满足低内存占用的要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 02:01:33