Python leyendo de un archivo y guardando en utf-8

81

Tengo problemas para leer un archivo, procesar su cadena y guardarlo en un archivo UTF-8.

Aquí está el código:

try:
    filehandle = open(filename,"r")
except:
    print("Could not open file " + filename)
    quit() 

text = filehandle.read()
filehandle.close()

Luego hago un poco de procesamiento en el texto variable.

Y entonces

try:
    writer = open(output,"w")
except:
    print("Could not open file " + output)
    quit() 

#data = text.decode("iso 8859-15")    
#writer.write(data.encode("UTF-8"))
writer.write(text)
writer.close()

Esto genera el archivo perfectamente, pero lo hace en iso 8859-15 según mi editor. Dado que el mismo editor reconoce el archivo de entrada (en el nombre de archivo variable) como UTF-8, no sé por qué sucedió esto. Por lo que mi investigación ha demostrado, las líneas comentadas deberían resolver el problema. Sin embargo, cuando utilizo esas líneas, el archivo resultante tiene un galimatías en caracteres especiales principalmente, palabras con tilde ya que el texto está en español. Realmente agradecería cualquier ayuda ya que estoy perplejo ...

aarelovich
fuente
2
¿Qué editor es este? ¿Qué versión de Python? A partir de aquí, este código parece ser completamente válido y debería funcionar como se esperaba…
filmor
Kate es la editora. La salida de Python --version es Python 2.7.5+
aarelovich
Probé su código con 2.6.8, 2.7.5+ y 3.3.2+, todo funciona bien. ¿Podría proporcionar algún ejemplo de entrada?
zero323
Dado que el texto se procesó en bytes sin procesar, el código de procesamiento invisible probablemente estropeó la codificación UTF8.
Mark Tolonen
3
Okay. Lo he resuelto. Fue principalmente mi culpa, lo siento a todos. Esto es lo que sucedió. El código proporcionado por @MarkTolonen funcionó si cambio iso-8859-15 en lugar de utf-8 al abrir el archivo. Sin embargo, como mi editor actualizó el archivo de la memoria después de haber cargado la codificación anterior, me mostró el galimatías. Cuando volví a abrir el archivo, me lo mostró bien. Gracias a todos y perdón por la molestia !!!
aarelovich

Respuestas:

201

Procese texto hacia y desde Unicode en los límites de E / S de su programa utilizando el codecsmódulo:

import codecs
with codecs.open(filename, 'r', encoding='utf8') as f:
    text = f.read()
# process Unicode text
with codecs.open(filename, 'w', encoding='utf8') as f:
    f.write(text)

Editar: el iomódulo ahora se recomienda en lugar de códecs y es compatible con la opensintaxis de Python 3 , y si usa Python 3, puede usarlo opensi no requiere compatibilidad con Python 2.

import io
with io.open(filename, 'r', encoding='utf8') as f:
    text = f.read()
# process Unicode text
with io.open(filename, 'w', encoding='utf8') as f:
    f.write(text)
Mark Tolonen
fuente
6
Hice exactamente lo que me dijiste. El mismo error que con la otra sugerencia
aarelovich
1
Lo tengo para trabajar. El problema era que el archivo original era iso-8859-15
aarelovich
10
Para cualquiera que venga a esto, tenga en cuenta que para Python3 open()y io,open()son lo mismo. Solo usa open(). Consulte la ayuda (abierta) y verá que es lo mismo que io.open (), incluso el encabezado dice Ayuda sobre la función incorporada abierta en el módulo io.
Shawn Mehan
1
@arturomp Tampoco funcionaría. io.openespera que se escriban cadenas Unicode, no cadenas de bytes. Realiza la codificación a la codificación declarada.
Mark Tolonen
1
Corrección @arturomp, no funcionará en Python 3. Python 2 convertirá implícitamente la cadena de bytes de nuevo a Unicode usando el asciicódec predeterminado , por lo que funcionará siempre que la cadena sea solo ASCII. Es por eso que Python 3 lo cambió ... evita que "funcionará a veces", lo cual es un error molesto de rastrear.
Mark Tolonen
10

También puede hacerlo mediante el siguiente código:

file=open(completefilepath,'r',encoding='utf8',errors="ignore")
file.read()
Siva Kumar
fuente
4

No puedes hacer eso usando open. utilizar códecs.

cuando abre un archivo en python usando la función abierta incorporada, siempre leerá / escribirá el archivo en ascii. Para escribirlo en utf-8 intente esto:

import codecs
file = codecs.open('data.txt','w','utf-8')
Fernando Freitas Alves
fuente
2
Intenté esto y me salió un error: UnicodeDecodeError: el códec 'utf8' no puede decodificar el byte 0xe9 en la posición 57: byte de continuación no válido
aarelovich
¿Está ahorrando con la codificación utf-8? mira, si estás leyendo de otro archivo que es ascii, primero debes decodificarlo.
Fernando Freitas Alves
El código es como lo ve. Lo que hice fue reemplazar la línea writer = open (output, 'w') con writer = codecs.open (output, 'w', 'utf-8') y eso me dio ese error
aarelovich