最近,在使用python的requests.post的时候,不论结果如何处理,得到的都是乱码。代码如下:
代码语言:python代码运行次数:0复制import requests
headers = {
"Accept-Encoding": "gzip, deflate, br",
}
param = '{"name":"tom"}'
resp = requests.post(url=url, data=param,headers=headers)
print(resp.content)
print(resp.text)
结果如图:
代码语言:python代码运行次数:0复制<xe3x80xe13x0cxe5xceSxffLxcdxc5x91xe2Vxe5xd1x8dx81xfax00axb8x0e7xd2xa5xcbGxf3@xb1x8dxf4~xcfxadxa3x8cx02xeaxc1xcdYxe4pxb39xb9xc1xdbxd7}xa3x02x13xa2x84}"xdaxcbxd6x8axbaxf4x0cxf6xc4xabx18x98xadPgxdcxbdxf3Wpxa3xb3pPx91}y2xe3xf4Ux1b&xd2uxe3uWxc4wx1dL0xd1x97xffxd5Nxf1dx87xb7:x9b=xf0rx15xceMxf0)Gxeexf9xadx15xedxfcxbdxca@xadONxdcx14xefyHxa3KUx87xaf5#1xf4xffxe3iExb7xeatxc5Lcx8ex0f`x83xbdxe1xecxb8xb1x9bxfax04Axdf_x88 xe5Axf2xdbOmH;xe0xa3:xacxf9xabxc9`x19xbex92i;
�7� b0���������S0Yw�#"f�k���y�ԓ�7�X����)u�!z�7��h�Ⱥ�1ޡ b0����4�J�w�th|b&�ɺ7"f�.�70�v�����E�"PB(�a27�ɘ��a��b21&��a
网上很多文章都说是编码的问题,比如修改编码:
代码语言:python代码运行次数:0复制resp.encoding='utf-8'
print(resp.text)
或者
print(resp.content.decode(encoding="utf-8"))
然而,问题依旧!!!!!
这时候,查看一下response返回结果的header信息
代码语言:python代码运行次数:0复制print(resp.headers)
看到的header信息如下:
代码语言:python代码运行次数:0复制{
'Date': 'Tue, 05 Feb 2023 12:31:52 GMT',
'Content-Type': 'application/json; charset=UTF-8',
'Transfer-Encoding': 'chunked',
'Connection': 'keep-alive', 'Vary': 'Accept-Encoding',
'Content-Encoding': 'br'
}
里面的{'Content-Encoding': 'br'} 这个引起了我的注意。于是就查了一下br是个什么东东??原来“br”是一种新的压缩算法,全称是Brotli。
我想,会不会是因为客户端不支持“br"这种算法导致的乱码呢?
于是,把requests.post的header修改了一下,把里面"br"算法删除,改为
代码语言:python代码运行次数:0复制headers = {
"Accept-Encoding": "gzip, deflate",
}
然后再次运行,运行结果非常非常正常!果然是因为这个“br"算法导致的问题
问题原因
痛定思痛,捋一下思路,问题本身出在Content-Encoding与Accept-Encoding这2个header配置上面。
Content-Encoding与Accept-Encoding的说明
当设置压缩格式后,服务器会根据用户设置的压缩格式对页面进行压缩,节省http请求的流量。
当服务端接收到请求,并且从header里拿到编码标识时,就可以选择其中一种方式来进行编码压缩,然后返给客户端。当response的header里没有编码标识的话,客户端就不知道服务端是用的哪种方式压缩的,所以需要Content-Encoding来标识服务端压缩时所用的压缩方式。
简单的说:
- Accept-Encoding:用来标识客户端能够理解的内容编码方式。
- Content-Encoding:用来标识主体进行了何种方式的内容编码转换。
Accept-Encoding 是HTTP协议的请求报文头,一般形式如
"Accept-Encoding": "gzip, deflate, br"
其中:
gzip
deflate
br 压缩算法 Brotli
代码语言:html复制Content-Encoding 是HTTP协议的响应报文头,一般形式如:
"Content-Encoding":"gzip,deflate,compress"
其中:
gzip 表明实体采用GNU zip编码(使用最多)
compress 表明实体采用Unix的文件压缩程序
deflate 表明实体是用zlib的格式压缩的
identity 表明没有对实体进行编码。当没有Content-Encoding header时, 就默认为这种情况
到这里,问题就彻底明了了,因为Content-Encoding设置的是“br”算法,但是客户端不支持br算法,所以,导致了乱码的现象。
问题解决
- 简单的解决 在请求的时候,把header的“br”算法删除掉
- 根本的解决undefined 如果非要保留br算法,python客户端应该怎么做呢? python里有个“brotli”包,就是针对这个算法的
# 安装brotli
pip install Brotli
对response进行解码
代码语言:python代码运行次数:0复制import brotli
import requests
headers = {
"Accept-Encoding": "gzip, deflate, br",
}
param = '{"name":"tom"}'
resp = requests.post(url=url, data=param,headers=headers)
resp = requests.post(url=url, data=param,headers=headers)
val = brotli.decompress(resp.content)
print(val)
大功告成!