记一次 python request brotli 处理问题
在爬取知乎评论的时候,遇到了 br 格式压缩的 response 的 content 。
由于未事先安装brotli 包,导致解析过程不顺利
现记录如下
brotli 安装
pip install brotli
python 代码
Header_ = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:101.0) Gecko/20100101 Firefox/101.0',
'Accept': '*/*',
# 启用 “content-encoding:br” 然后返回的是br格式的压缩数据
'Accept-Encoding': 'gzip, deflate, br',
'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
'Connection': 'keep-alive',
'Referer': 'https://www.zhihu.com/question/522084520/answer/2394053852',
}
res = requests.get(
"https://www.zhihu.com/api/v4/answers/2394053852/root_comments?order=normal&limit=10&offset=0&status=open", headers=Header_)
print(res, res.headers.get('Content-Encoding'))
此处 res 已经是 br格式的数据了。
如下正常处理数据即可
if((res.status_code == 200) and (res.headers.get('Content-Encoding') == 'br')):
root_comment = res.content
print(root_comment)
request 在安装了 brotli 后会自己去解析 数据格式,因此代码上不要做任何修改和操作。
如果是先装request ,在代码执行过程中 安装了 brotli ,需要重启下项目工程
我的版本如下
PIP list 结果
brotlipy 0.7.0
requests 2.27.1
request包代码追溯如下
# request 使用 urllib3
# urllib3.response 会自己去 import Brotli
try:
import brotli
except ImportError:
brotli = None
# 自动解析数据格式
def _get_decoder(mode):
if "," in mode:
return MultiDecoder(mode)
if mode == "gzip":
return GzipDecoder()
if brotli is not None and mode == "br":
return BrotliDecoder()
return DeflateDecoder()
歧途:
网上流传代码 一般如下
if((res.status_code == 200) and (res.headers.get('Content-Encoding') == 'br')):
root_comment = brotli.decompress(res.content).decode('utf-8')
print(root_comment)
多了一个“brotli.decompress”的步骤 ,会导致可能的报错类似于
brotli.brotli.Error: Decompression error: b'PADDING_2'
brotli.error: BrotliDecompress failed
实际上无需再去decompress了,网上如果是让你再去decompress的代码,可能是版本较老。
希望本文能节约大家的时间 。
题外话:如果在 Header 里面去掉 “ 'Accept-Encoding': 'gzip, deflate, br' ”,
即视为请求不使用 br 压缩。直接解析即可。
参考文献:
https://stackoverflow.com/questions/63809144/python3-8-brotli-brotli-error-brotlidecompress-failed

浙公网安备 33010602011771号