2010-04-22 29 views
29

He descargado una página web en mi script python. En la mayoría de los casos, esto funciona bien.En Python, ¿cómo decodizo la codificación GZIP?

Sin embargo, este tenía un encabezado de respuesta: codificación GZIP, y cuando traté de imprimir el código fuente de esta página web, tenía todos los símbolos en mi masilla.

¿Cómo decodificar esto a texto normal?

Respuesta

64

Uso zlib para descomprimir contenido comprimido de la web.

import zlib 

... 
# f=urllib2.urlopen(url) 
decompressed_data=zlib.decompress(f.read(), 16+zlib.MAX_WBITS) 
+0

me salvaste la vida) – Oduvan

+3

¿podrías comentar cuál es el segundo argumento para descomprimir? ¿Y por qué es tan ... bueno ... extraño? – DataGreed

+1

@DataGreed, el segundo argumento es para el tamaño de la ventana, consulte la respuesta de John Machin a continuación. – YOU

25

Descomprime la secuencia de bytes utilizando el módulo gzip incorporado.

Si tiene algún problema, mostrar el código mínimo exacta que utilizó, el mensaje de error exacto y rastreo, junto con el resultado de print repr(your_byte_stream[:100])

Información

1. Para una explicación de la confusión gzip/zlib/deflate, lea la sección "Otros usos" de this Wikipedia article.

2. Puede ser más fácil usar el módulo zlib que el módulo gzip si tiene una cadena en lugar de un archivo. Por desgracia, la Python docs son incompletas/incorrecto:

""" zlib.decompress (cadena [, [wbits, bufsize]]) ... El valor absoluto de wbits es la base de dos logaritmo del tamaño de la buffer histórico (el "tamaño de ventana") utilizado al comprimir datos. Su valor absoluto debe estar entre 8 y 15 para las versiones más recientes de la biblioteca zlib, los valores más grandes dan como resultado una mejor compresión a expensas de un mayor uso de memoria. es 15. Cuando wbits es negativo, se suprime el encabezado gzip estándar; esta es una característica no documentada de la biblioteca zlib, utilizada para compatibilidad con el formato de archivo de compresión de descompresión. "" "

En primer lugar, 8 < = log2_window_size < = 15, con el significado dado anteriormente. Entonces, lo que debería ser un arg separado es kludged en la parte superior:

arg == log2_window_size significa que la cadena está en formato zlib (RFC 1950; lo que el HTTP 1.1 RFC 2616 confusamente llama "desinflar").

arg == -log2_window_size significa asumir cadena está en formato de desinflado (RFC 1951; lo que la gente que no leyeron el HTTP 1.1 RFC cuidadosamente llevan a la práctica)

arg == 16 + log_2_window_size significa asumir cadena está en formato gzip (RFC 1952). Para que pueda usar 31.

La información de arriba está documentada en el zlib C library manual ... Ctrl-F búsqueda windowBits.

+0

Gracias por la exhaustiva información sobre el tema. – temoto

8

utilizo algo así:

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 
3

para python3

probar este

import gzip 

    fetch = opener.open(request) # basically get a response object 
    data = gzip.decompress(fetch.read()) 
    data = str(data,'utf-8') 
-1

Puede utilizar urllib3 para decodificar fácilmente gzip.

urllib3.response.decode_gzip(response.data) 
+0

¿Por qué se ha bajado este valor? –

+1

@SamP Creo que porque no funciona como está, no explica nada. Si lo intentas, seguro que obtendrás algunos errores. Esa no es una respuesta válida en absoluto. – erm3nda

+0

Me gusta el paquete 'requests', que podría manejar' gzip' automáticamente – WeizhongTu

1

Similar a la respuesta de Shatu para python3, pero dispuestas de manera diferente:

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

Este método permite envolver la gzip.decompress() en un try/except para capturar y pasar el OSError que da como resultado situaciones en las que puede obtener datos mixtos comprimidos y no comprimidos. Algunas cadenas pequeñas en realidad se hacen más grandes si están codificadas, por lo que los datos simples se envían en su lugar.

Cuestiones relacionadas