python3.8 brotli brotli.error: BrotliDecompress fehlgeschlagen?

Sep 09 2020

mycode python3.8

brotli = 1.0.9

Verwenden Sie Request Get URL, Header verwenden Accept-Encoding = "br". Ich muss Decode br verwenden, weil ich denke, dass Accept-encoding = br besser ist

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

Fehler auslösen

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

Antworten

3 LaurentPinson Nov 03 2020 at 05:11

Dies wird nirgends in der Dokumentation von Anfragen erwähnt, aber sobald brotli installiert ist, wird es direkt von Anfragen bearbeitet.

Dies bedeutet, dass response.content automatisch dekodiert wird (ähnlich wie bei gzip). Das musst du nicht tunbrotli.decompress(response.content)

Wenn brotli nicht installiert ist, wird keine Fehlermeldung angezeigt. Stattdessen bleibt response.content verschlüsselt ...

bearbeiten :

Beim Durchsuchen des Anforderungscodes stellte ich fest, dass Anforderungen urllib3.response verwenden, was die Verwendung von Brotli implementiert.

Beim Laden sucht urllib3.response nach einem Import von Brotli:

try:
    import brotli
except ImportError:
    brotli = None

Beim Decodieren einer Antwort wird dann ein geeigneter Decoder verwendet:

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

Wenn also Brotli installiert ist, erfolgt die Dekodierung, da sonst nichts passiert und der Benutzer nicht gewarnt wird.