python3.8 brotli brotli.error: BrotliDecompress thất bại?

Sep 09 2020

mycode python3.8

brotli = 1,0,9

sử dụng url request get, tiêu đề sử dụng Accept-Encoding = "br" Tôi cần sử dụng decode br, vì tôi nghĩ sử dụng accept-encoding = br tốt hơn

import brotli
import requests 
headers = {}
headers['Accept'] = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"
headers['Accept-Encoding'] = "gzip, deflate, br"
headers['Host'] = "book.douban.com"
headers['Referer'] = "book.douban.com"
headers['Sec-Fetch-Dest'] = "document"
headers['Sec-Fetch-Mode'] = "navigate"
headers['Upgrade-Insecure-Requests'] = "1"

s=requests.Session()
url="https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4"
try:
    response = s.get(url, headers=headers)
except:
    return ""
if response.status_code == 200:
    print(response.headers)
    if response.headers.get('Content-Encoding') == 'br':
        data = brotli.decompress(response.content)
        data1 = data.decode('utf-8')
        return data1
    else:
        return response.text
return ""

nêu ra lỗi

data = brotli.decompress(response.content)
brotli.error: BrotliDecompress failed

Trả lời

3 LaurentPinson Nov 03 2020 at 05:11

Điều này không được đề cập trong tài liệu về các yêu cầu nhưng khi brotli được cài đặt, nó sẽ được các Yêu cầu xử lý trực tiếp.

Điều này có nghĩa là response.content sẽ được tự động giải mã (tương tự như gzip). Bạn không cần phải làmbrotli.decompress(response.content)

nếu brotli chưa được cài đặt, bạn sẽ không nhận được bất kỳ thông báo lỗi nào. Thay vào đó, response.content sẽ vẫn được mã hóa ...

chỉnh sửa :

đào mã Yêu cầu, tôi phát hiện ra rằng Yêu cầu sử dụng urllib3.response triển khai việc sử dụng Brotli.

khi tải, urllib3.response sẽ tìm kiếm bản nhập Brotli:

try:
    import brotli
except ImportError:
    brotli = None

thì khi giải mã một phản hồi, nó sẽ sử dụng bộ giải mã thích hợp:

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()

do đó nếu Brotli được cài đặt, việc giải mã sẽ xảy ra nếu không sẽ không có gì xảy ra và không có cảnh báo cho người dùng.