python解压br格式文件brotli安装使用

在爬虫时,遇见br格式的压缩,当时不知道还有这种压缩格式,主要是也没在意,所以导致无论怎么更换编码格式都无法解析到需要的数据,最后才知道是少安装了brotil库。

什么是br

br 指的是 Brotli,是一种全新的数据格式,无损压缩,压缩比极高(比gzip高的)

Brotli具体介绍:https://www.cnblogs.com/Leo_wl/p/9170390.html

Brotli优势:https://www.cnblogs.com/upyun/p/7871959.html

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,则默认返回的是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格式的数据了。如果我们卸载brotli后,会出现乱码情况。

b'a$\xd8\x00 \x7f\xef;\xed\xab\xfeV\x1b\xd8\xd5\t\x91\xf2\x87\xa6J\x0c\xb6\xb0W\x0e\xa0\x118\x84$\xcb)\x04\xc9^<\xe3\xaa\xd6{\x0f\xfc\xaf\xbd?\xad\xc18$B\x82cP\xcc\xb7\xd4\x87bP\xe0\x90\xa5\xbb\x9a\xd2\xf6\x9e\xbb\'\xe9\xaa\x17U\xba*\xbd\xe8\xb8\x08MfC\xdf\xb9\xe9OH\x84\x8d\xcd\xffB\xcb\xc8\xa72_\xc7H\x83\xeb\xef\x99x)"v\xbf\xcc\xae2\xdb\x1duK{W\xd947\x1c\x95\xf6\x7fv\x95}>\xbcrgn\xb6\xb4\x0b\x9a\x0b\xb9\x82\x1b\x83\xa5bi\xfd\xcc\xa7\xecw7\xf7J\xbb4\xb7\x17\x9bC\x0f\x9b\xdb\x8b\xf5\xe7\xd7\xcd\x89\x1b\x93\x83\'\xea\xcf\xaf\x9bC\x0fW\xbf~\x9b\xde\xbf:}\xb8T-\x1e)\xad\xd2\x9d\x9f\xefl\xec\xed(m\xd6V9v\xb4\xd1\xa5\xbd\xabtg;\xed\x94\xfc\xd3SU\xf2\x00\xc9\xdfZ\xa6\xbb\xad\xb7\xb9\xd7\xd92\xfc\xd1\x87\x84\x91\xa5\x85\x04Ci\x95\xfd\x90\xdc\xbc\xb4\x0b\x02\x94V\xd9\xd8\xdb\xd1\x81\xaa\xa2\xb2\x9fMs\xebz?\xf8#Z\xa8\x07J\x183\xab\x08\x89\xe8=\x91\xb7\xfb\xeb/\xba0\xd8\xd4+mh\x95\xcd\xdd\xb9~gmw\xd4[\x18,\xec\xe84\xfd\xe7\x14@P\xd4\xf2\xbfV9\xef\x0f+\xd2\xfdq\x04\x8c9\x05\xd13\x8cRK\xab\xccw\x17z\xfd\x11\x83n(\xad\xb2\xc7\x8f%K\xbb\x94V\x99\x1f\xcc}\xf7\xa3\x98\x9b\xab1\x92\x98(\xa8\x88{i\x95ao4\xda\xd4\xeb\x0cG\xdd\xd1\x96a\xe7\xe8\x10V\xe9\\:\x01\x8dH\x93\xa7\x99\x95v\xc1\xb2\xa7Uz\xdbG\x0b\xdd\xd2\xde\xb5\xe7\xff\x8c\xeb\xaf\xd1h~\xd8\x9e\x99\xd9\xb4\x8e\xff8\x83\xfb\xe3Z\xfb\xe7\x9a\x1d\xa3\xdel\x7f8;X{\x89\n|\xd0`\xcd\x86\x99\xdel\xaf\xff\xc7\xda\xfeL\x7f\xcb\xd6\x8d[\xfe\x9a\x1f\xae\x99\x1f\xcel\x9a[\xd7\xfb\xb5\x96\x996Z\xf1|)\xfa\x01O\x1ar+\x87\x00\xb9}\xdc\xd3\xd2\xed\x1c\x84\xa4\x87S\xaa\xab\xb0\xdb\x98\xe9\xb1\xc5\xd5\x95\x95\xe3\x8d(\xd1\\\xbcS\xef?\xc0\xd2j\xaeL\t\xd5\xa9\xa6\x18(`F\x8a\x0c\xdf\xd5`\xf2\xef\x7f\xc0\x044E4vO7\xc2\x10M{r%\xea\xb3|4\x10\x8b\x85)\x88\xc9\xd9\xd4\xc0\xc3\x8a\xe8\x0c\x109S3\x08\x1c\rX\r\x03\xa7x\x18%qw5L\x08\xb0I\xaf~\xf0\xba\xbe}\xa5y?n\x0e|\xd2d\xbb\x92c\xd1\xc7NK8\x82\xc1\x1cI\x01\rH\x98"n\xec\xd1\x90\x93k8\x90\x89\x8a\n\x99D\xd2\xd5\xb8\x8f\x18\xabI\x08\x0ex\x0f\x04\x82\x00\xcf$F\xb7xA\xf6,\x90\x1c\x10\x1d\x14\x05\xc3(\x0c\x00\xdf\x10\x0b\x1e\xd4\xc5\x03\x8c\x89\xd0\xbdsOY\xd7\xc6\xd5\xf2\xc7\xea\xcb\xad\xfa\xe1\xf9_\xaa#\'&o\xbfT+W~\x8d\x93\x83.\x00\xf6\xe7\xd5\xfd\xb9\x19L\xc6\x00\xa2\xc1\xe6D\x9a\xba\x14)@\x8f\x07\xd1\x10C4]5!\xd1L\xc9\x97&\xd1\n\x01\x82\x1a\xef\x9e\x81,\xce\x1cHf\x19!rP:)#\x1b\x87\x01\xe0\x14\xbfV\x9aJ\x88\x04\x18\xad;i\xb5]c\xb2\xfcx\xf5\xdb\x85\x7f\x0c\x06k\xdem\xb0\xcd\xfd\xf7\x05\x02`0LW\xe75\x10\x00(\x98\x9d\xbb7\xefh)"\x87\xca\x8c\x8a @1X\xc52D\xd4\x10M\xf7Ozu\xdd\x95\n8\xb8\xd5\x18\xe0D\x99\xae\xe4\x02a\xf7tqO0F\x87\x94d\x1a\x1d\x90\xfc\x08[e\xb8e\r\xea<\xec\xd91/\x86b\xc3%\xa8\xa4\x08i\xb0\xaa\xcd[\xd6W\x1e\xad.\x9f\xaa\xde\x9dj\x0e=\x9c\x1c\xb8\xd3\x1cz\xd2\x1czX-=Q\xe5\xd1\t H\xbd`\xb2\x083r3V1\x13\xd1cA\xc6\x84\xce\xc9\xe4\x19&\x16\xe1\xa6\xa2\xca\xd5f\xa9l\xb4\x8a\x06\x121`\x98\xeat\x97\x99Ah\xee!\x08\xc6.(\x05\xdc<\x9cw\xc5\xc0\t\xd2\xbc\xb6\x03\xb18\x810\x06eB\xd2:K}\x93G?\xea\xf7\x1f\xea\xfb\x8f\xab\xe5o\xf5\xdb\x8f\xab_O\xae./U7^\xa9s\x80\x89\xd2\xa6\xfa\xf5\xf1r2@\x00\x13!s\xa6\xae\x1c0\x80\xf2\x8c\xca)PP\x82!\xd4\x02|\xd1\xd2\xa5)\xb4\x02\x18\xa0_\x01I\x061Rc\x17\xe3\xc9\xd8k#[\x80j\x98\x99k\x86T\xf8f\xbbD\xe0\x84\xc09G\x0e\x1c\xee\xaa\x80\x04\x80\xc5\x81\xf4\xdb\xbc\xde?]\xfe\xd1|\xb8\\\xbf\xfd8\xbd\xb0\xf2Ks\xf4Zu\xf3m\xfd\xf5\xcd\x90?gl\x1a\x0cf y\n\xbb\'(A\x18JU\xa4\x82}\xb1\x84 \x11\xb1\xdb\x83\x08\x8e\x12E\xbdx\xd3\xf4ZM@\x04\xa0\xa6d\xb3f#\x04\xaa\xa6B\xb6\x87\xc0\x04f\xa9\x1e\xc4\x1c&\x06\x81S\x04{=S\xe4H\x04\x17(\x1e\t+\xcf\xe4\xc9\xe2\xd5\xc9\x85[\xf5\xf2x\xfa\xe1\xd6\xf4\xdd\xf7f\xdc~\xd6D)Mv9p}\n\x14\x0e0"\t\x9e\x05\xf3\x8e\xa7"\x05\xe8s\x14\x19\x01n)\x0c\x16Z\xc4\xf2\xe1K\x14\xa8j\x00o\xb6\x10\'k8#\x89\x93\x87e{\x9a\x16\xa9\x81\x92h\x98\xa1j\x108g\xf9\x12\x1c\xcc\x049\xc5a\xb1\xb0\xb9;^\xfd~\xb7z~\xbe:\xf1\xa4\xba\xb9\xf2r\x94\x06N1\xdf:\x80!\xa6s\x8f\x87\xc50\xb5\xa7\x17\xf1Cu\xc6\x93`\x0e\x02\xa0\x19\x8c\x94\x06\x86\xc9\xf2^\xd6I\xfa\xf8\xeb\xb3\x00\xa0H\x84\x9ah\xbd\x8c\x1a7\x9b\xb3\xf0\xf9//\xc02\xc1\xcd\x04\x1c\x02\xa7H3\xa4\xa3\x05\xbb)\x07\xd6\x95,o\x1e\x1f\xae\x96\x8eO\xaf\xd3\xebK\xd5\xe9\xbb\xf5\xbd\xcf\xcd\xa1\'\x93\xdbg\xaa\xa5\xe3\xd5\xf7\xb3\xd5\xd7\x83\xf5\xb57\xa5\xcfd\x8cK\x8c\xa59J\x0b\x136C\x08\x04\x19D\xc5\x05\x0c\xd4DRX\xb21\t\x9b"\xbb\x01\xa7\x8aS/Oj\x01\xf7?\xf9\x89XUv2[$\x95\x08,\x03\x90\xd5\xd4\xee\xe5\xc8\x90\x1e@\xcc\x90J\xddIa[ pJ\xbf\x1f,\x98\x0c\x05\x12\\y\x04\x95\x16\xa7\xb7\xceOo\x9do\xc6\x8b\xcd\xc5\xf7\xcdx\xb1\xb9\xf5\xa2\x19/V\x8fK\xf5UTF2KH\x02\x10,\x89\xd9\xc03/\x15Y`\xd5^\xdf\x198\x9c\xd4\x83\x13\xaa`0\xc8j)\xd3dz\x10\xe8 \xa9\xa9\xe5\x1c\x9e\xca\x11\x8e\xa4\x942n\xca\xfc\xd2\x1d$\xcd\x08\x11\x11R\x17\x08\x1co\x9e\xf1\x7f\xad2\xdf]?\xd7\xef\x8e\xe6\x06\xfd\xd2\xdeU\xe6\xbb\xeb{\x9d\x15\xd5Q\xda\x1a?q\x83^g\xae?\xdb\xdb^\xda\xf8\xa5\x87\r\xe7v\xf6J\x9b\xa0UF\x83Qw\xd3\xaf\\\x0fQi\xcf\x9eV\xd94X\x8f\xe5~\x04D\x10h\x84\xe0\x1a\xb0\xd3\xf7g\x91\x80\x0c\xfa\x17\xa4\xc1\xbf\xbd\xb4J\x7f\xb0\xad\xae\xd9j\xb0\xcf\x80\xb6\xd0@\x904\xef\xdek\x07\xb3\xbdf]\xb4\xb3y\xb8\xbe\xb4K\xd9c\x00\x03'

如下处理数据即可

if res.headers.get('Content-Encoding') == 'br':  
    data = brotli.decompress(res.content)        
    print(data.decode('utf-8'))                  
else:                                            
    print(res.text)                              

这样就获取到了数据

{"data":{"list":[{"account_id":"1674275076306951","account_name":"瞎烤瞎涮牛肉涮烤主题餐厅","app_key":35,"detail":{"ad_customer_id":"5278049",

题外话:如果在 Header 里面去掉 “ 'Accept-Encoding': 'gzip, deflate, br' ”,即视为请求不使用 br 压缩。直接解析即可,此时无需使用brotli来解压。

补充下:BrotliDecompress failed错误问题

刚开始我用request库时发现,对返回的response数据必须要引入brotli,这样才能解压缩数据,如果不引入无法解析数据,还是会反回乱码数据

import brotli
res = requests.get(url,headers = header,verify=False)
print(res.content)
print(res.text)

if res.headers.get('Content-Encoding') == 'br':
    data = brotli.decompress(res.content)
    print(data.decode('utf-8'))
else:
    print(res.text)
但是在我使用httpx后,发先再使用brotli.decompress()方法,会造成报错

Traceback (most recent call last):
  File "/****", line 61, in
    data = brotli.decompress(res.content)
brotli.error: BrotliDecompress failed

这时无需引入brotli库,httpx会自动引入,自动调用

import json
finish_data = []
with httpx.Client(http2=True, verify=False) as client:
    cookies = httpx.Cookies()
    res = client.get(url,headers = header)
    if res.headers.get('Content-Encoding') == 'br':
       data = res.content.decode('utf-8')
       print(data)
       
       else:
          print(res.text)

你可能感兴趣的:(python3,python)