Lectura de caracteres utf-8 desde un archivo gzip en python


Estoy tratando de leer un archivo gunzipped (.gz) en python y estoy teniendo algunos problemas.

Utilicé el módulo gzip para leerlo, pero el archivo está codificado como un archivo de texto utf-8, por lo que finalmente lee un carácter no válido y se bloquea.

¿Alguien sabe leer archivos gzip codificados como archivos utf-8? Sé que hay un módulo de códecs que puede ayudar, pero no puedo entender cómo usarlo.

Gracias!

import string
import gzip
import codecs

f = gzip.open('file.gz','r')

engines = {}
line = f.readline()
while line:
    parsed = string.split(line, u'\u0001')

    #do some things...

    line = f.readline()
for en in engines:
  print(en)
Author: Juan Besa, 2009-12-10

5 answers

No veo por qué esto debería ser tan difícil.

¿Qué estás haciendo exactamente? Por favor explique "eventualmente lee un carácter inválido".

Debe ser tan simple como:

import gzip
fp = gzip.open('foo.gz')
contents = fp.read() # contents now has the uncompressed bytes of foo.gz
fp.close()
u_str = contents.decode('utf-8') # u_str is now a unicode string

EDITADO

Esta respuesta funciona para Python2 en Python3, por favor vea la respuesta de @SeppoEnarvi en https://stackoverflow.com/a/19794943/610569 (utiliza el modo rt para gzip.open.

 19
Author: sjbrown,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:47:09

Esto es posible en Python 3.3:

import gzip
gzip.open('file.gz', 'rt', encoding='utf-8')

Observe que gzip.open() requiere que especifique explícitamente el modo de texto ('t').

 30
Author: Seppo Enarvi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-06 18:41:47

Tal vez

import codecs
zf = gzip.open(fname, 'rb')
reader = codecs.getreader("utf-8")
contents = reader( zf )
for line in contents:
    pass
 21
Author: Jochen Ritzel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-12-10 20:21:02

Lo anterior produjo toneladas de errores de decodificación. Usé esto:

for line in io.TextIOWrapper(io.BufferedReader(gzip.open(filePath)), encoding='utf8', errors='ignore'):
    ...
 4
Author: Yurik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-10 20:13:14

En forma pitónica (2.5 o mayor)

from __future__ import with_statement # for 2.5, does nothing in 2.6
from gzip import open as gzopen

with gzopen('foo.gz') as gzfile:
    for line in gzfile:
      print line.decode('utf-8')
 0
Author: Douglas Mayle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-12-10 20:26:12