问题
requests请求一个API,发现响应乱码,响应的二进制以a开头
b'a\x04(\x00 \x979 ...
排查过程
冷静分析,查看请求头和响应头。
请求头:
accept-encoding: gzip, deflate, br
响应头:
Content-Type: application/json; charset=utf-8
Content-Encoding: br
响应头写的很清楚,响应体压缩方式为br(Brotli)。所以在venv中安装Brotli,并尝试显式解压响应体
import brotli
brotli.decompress(response.content)
报错解压失败。print一下response.content,发现已经是明文。
解决方法
在当前环境中安装brotli,然后requests会自动解压br编码,放到response.content中。
补充资料
1. Brotli最初发布于2015年,用于网络字体的离线压缩。Google软件工程师在2015年9月发布了包含通用无损数据压缩的Brotli增强版本,特别侧重于HTTP压缩。其中的编码器被部分改写以提高压缩比,编码器和解码器都提高了速度,流式API已被改进,增加更多压缩质量级别。新版本还展现了跨平台的性能改进,以及减少解码所需的内存。与常见的通用压缩算法不同,Brotli使用一个预定义的120千字节字典。该字典包含超过13000个常用单词、短语和其他子字符串,这些来自一个文本和HTML文档的大型语料库。预定义的算法可以提升较小文件的压缩密度。使用brotli取代deflate来对文本文件压缩通常可以增加20%的压缩密度,而压缩与解压缩速度则大致不变。
2. 当没有安装brotli的时候,requests尝试解压br失败就会直接把二进制数据放到content里。当安装后,requests就会自动解压并把明文放到content里。所以这是一例某库是否安装会影响requests.content内容的例子。
3. gzip是可以自动解压的(python内置)。
关键词
requests br 二进制 乱码 brotli