python3.8 brotli brotli.error : BrotliDecompress 실패?

Sep 09 2020

mycode python3.8

브로 틀리 = 1.0.9

사용 요청 URL 가져 오기, 헤더 사용 Accept-Encoding = "br"나는 accept-encoding = br 사용이 더 좋다고 생각하기 때문에 디코딩 br을 사용해야합니다.

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 ""

오류를 일으키다

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

답변

3 LaurentPinson Nov 03 2020 at 05:11

이것은 요청 문서 어디에도 언급되어 있지 않지만 일단 brotli 가 설치되면 요청에 의해 직접 처리됩니다.

이는 response.content가 자동으로 디코딩된다는 것을 의미합니다 (gzip과 유사). 당신은 할 필요가 없습니다brotli.decompress(response.content)

brotli가 설치되어 있지 않으면 오류 메시지가 표시되지 않습니다. 대신 response.content는 인코딩 된 상태로 유지됩니다.

편집 :

Requests 코드를 파헤쳐 보면 Requests가 Brotli의 사용을 구현하는 urllib3.response를 사용한다는 것을 알았습니다.

로드시 urllib3.response는 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()

따라서 Brotli가 설치되어 있으면 디코딩이 수행되고 그렇지 않으면 아무 일도 일어나지 않으며 사용자에게 경고가 표시되지 않습니다.