Python requests请求接口返回乱码 压缩响应解压解码报错解决
问题根因
- 你在请求头的
accept-encoding字段里声明了支持br(即Brotli)压缩格式,拿到的响应开头字节b'\x83\xc5\x12'就是Brotli压缩流的典型特征,并非gzip或deflate格式,用gzip解压必然报错。 - requests本身不内置Brotli解压能力,只有运行环境安装了Brotli相关依赖时,才会自动解压br格式的响应;未安装依赖时,
.content会直接返回压缩后的原始二进制流,直接调用.text解码就会出现乱码。 - 你之前写的手动解压逻辑存在两处硬错:一是把二进制字节流强转为字符串再传入
StringIO,而压缩解压操作处理的是字节流,必须用BytesIO承载;二是选错了解压算法,用gzip处理Brotli流完全不匹配。
解决方案
方案1(推荐,无额外代码改动)
- 先安装Brotli解码依赖,执行命令:
pip install brotli - 依赖安装完成后,原有代码不需要做任何解压相关修改,直接访问
get_tf_data.text获取文本内容,或者调用get_tf_data.json()直接解析接口返回的JSON数据即可,requests会自动识别响应头里的压缩标识,完成解压、解码全流程。
方案2(手动解压逻辑)
如果需要手动控制解压流程,参考如下代码:
import brotli import json # 原有请求逻辑保持不变 session_request = requests.Session() session_request.headers.update(default_header) get_tf_data = session_request.get(url_for_token) # 直接对二进制内容做Brotli解压,不要转字符串 decompressed_bytes = brotli.decompress(get_tf_data.content) # 按utf-8解码为明文 plain_text = decompressed_bytes.decode('utf-8') # 解析JSON api_data = json.loads(plain_text)
注意:排查压缩格式问题时,可以先打印响应头确认编码类型:
print(get_tf_data.headers.get('Content-Encoding')),返回br对应Brotli压缩,返回gzip对应gzip压缩,不要混用解压算法。另外绝对不要用str(字节对象)[2:-1]的方式处理二进制响应,这种写法会把字节的打印表示当成内容,直接破坏原始数据结构。
内容的提问来源于stack exchange,提问作者viltx
相关产品推荐
相关产品推荐

