J'ai téléchargé une page Web dans mon script python. Dans la plupart des cas, cela fonctionne bien.
Cependant, celui-ci avait un en-tête de réponse: encodage GZIP, et quand j'ai essayé d'imprimer le code source de cette page Web, il y avait tous les symboles dans mon PuTTY.
Comment décoder cela en texte normal?
J'utilise zlib pour décompresser le contenu gzippé du Web.
import zlib
...
# f=urllib2.urlopen(url)
decompressed_data=zlib.decompress(f.read(), 16+zlib.MAX_WBITS)
Décompressez votre flux d'octets à l'aide du module gzip intégré.
Si vous avez des problèmes, affichez le code minimal exact que vous avez utilisé, le message d'erreur exact et traceback, ainsi que le résultat de print repr(your_byte_stream[:100])
Plus d'informations
1. Pour une explication de la confusion gzip/zlib/dégonflage, lisez la section "Autres utilisations" de cet article Wikipedia .
2. Il peut être plus facile d'utiliser le module zlib que le module gzip si vous avez une chaîne plutôt qu'un fichier. Malheureusement, les documents Python sont incomplets/erronés:
"" "zlib.decompress (string [ wbits [ bufsize]]) ... La valeur absolue de wbits est le logarithme de base deux de la taille du tampon d'historique (la" taille de fenêtre ") utilisé lors de la compression des données. la valeur absolue doit être comprise entre 8 et 15 pour les versions les plus récentes de la bibliothèque zlib, des valeurs plus grandes entraînant une meilleure compression au détriment d'une plus grande utilisation de la mémoire. La valeur par défaut est 15. Lorsque wbits est négatif, l'en-tête gzip standard est supprimé; il s'agit d'une fonctionnalité non documentée de la bibliothèque zlib, utilisée pour la compatibilité avec le format de fichier de compression de décompression. "" "
Tout d'abord, 8 <= log2_window_size <= 15, avec la signification donnée ci-dessus. Ensuite, ce qui devrait être un argument séparé est placé en haut:
arg == log2_window_size signifie que la chaîne est au format zlib (RFC 1950; ce que le HTTP 1.1 RFC 2616 appelle confusément "dégonfler").
arg == -log2_window_size signifie que la chaîne est au format dégonflé (RFC 1951; ce que les gens qui n'ont pas lu le RFC HTTP 1.1 ont soigneusement mis en œuvre)
arg == 16 + log_2_window_size signifie que la chaîne est au format gzip (RFC 1952). Vous pouvez donc utiliser 31.
Les informations ci-dessus sont documentées dans le manuel de la bibliothèque zlib C ... Ctrl-F recherche de windowBits
.
J'utilise quelque chose comme ça:
f = urllib2.urlopen(request)
data = f.read()
try:
from cStringIO import StringIO
from gzip import GzipFile
data2 = GzipFile('', 'r', 0, StringIO(data)).read()
data = data2
except:
#print "decompress error %s" % err
pass
return data
Pour Python 3
Essayez ceci:
import gzip
fetch = opener.open(request) # basically get a response object
data = gzip.decompress(fetch.read())
data = str(data,'utf-8')
Similaire à la réponse de Shatu pour python3, mais arrangé un peu différemment:
import gzip
s = Request("https://someplace.com", None, headers)
r = urlopen(s, None, 180).read()
try: r = gzip.decompress(r)
except OSError: pass
result = json_load(r.decode())
Cette méthode permet d'encapsuler gzip.decompress () dans un essai/sauf pour capturer et transmettre l'OSError qui entraîne des situations où vous pouvez obtenir des données mixtes compressées et non compressées. Certaines petites chaînes deviennent en fait plus grosses si elles sont encodées, donc les données simples sont envoyées à la place.
Si vous utilisez le module Requests
, alors vous n'avez pas besoin d'utiliser d'autres modules car les gzip
et deflate
transfer-encodings sont automatiquement décodés pour vous.
Exemple:
>>> import requests
>>> custom_header = {'Accept-Encoding': 'gzip'}
>>> response = requests.get('https://api.github.com/events', headers=custom_header)
>>> response.headers
{'Content-Encoding': 'gzip',...}
>>> response.text
'[{"id":"9134429130","type":"IssuesEvent","actor":{"id":3287933,...
Le .text
La propriété du réponse sert à lire le contenu dans le contexte texte.
Le .content
La propriété de la réponse sert à lire le contenu dans le contexte binaire.
Voir la section Binary Response Content sur docs.python-requests.org