it-swarm.com.de

Wie konvertiert man eine Datei in Python in utf-8?

Ich muss ein paar Dateien in Python nach utf-8 konvertieren, und ich habe Probleme mit dem Teil "Konvertieren der Datei".

Ich möchte das Äquivalent machen von:

iconv -t utf-8 $file > converted/$file # this is Shell code

Vielen Dank!

48

Sie können das Modul codecs wie folgt verwenden:

import codecs
BLOCKSIZE = 1048576 # or some other, desired size in bytes
with codecs.open(sourceFileName, "r", "your-source-encoding") as sourceFile:
    with codecs.open(targetFileName, "w", "utf-8") as targetFile:
        while True:
            contents = sourceFile.read(BLOCKSIZE)
            if not contents:
                break
            targetFile.write(contents)

EDIT: BLOCKSIZE-Parameter hinzugefügt, um die Dateigröße der Datei zu steuern.

46
DzinX

Das hat in einem kleinen Test für mich funktioniert:

sourceEncoding = "iso-8859-1"
targetEncoding = "utf-8"
source = open("source")
target = open("target", "w")

target.write(unicode(source.read(), sourceEncoding).encode(targetEncoding))
27
Staale

Danke für die Antworten, es funktioniert!

Und da die Quelldateien in gemischten Formaten vorliegen, habe ich eine Liste von Quellformaten hinzugefügt, die nacheinander ausprobiert werden sollen (sourceFormats), und ich UnicodeDecodeError probiere das nächste Format:

from __future__ import with_statement

import os
import sys
import codecs
from chardet.universaldetector import UniversalDetector

targetFormat = 'utf-8'
outputDir = 'converted'
detector = UniversalDetector()

def get_encoding_type(current_file):
    detector.reset()
    for line in file(current_file):
        detector.feed(line)
        if detector.done: break
    detector.close()
    return detector.result['encoding']

def convertFileBestGuess(filename):
   sourceFormats = ['ascii', 'iso-8859-1']
   for format in sourceFormats:
     try:
        with codecs.open(fileName, 'rU', format) as sourceFile:
            writeConversion(sourceFile)
            print('Done.')
            return
      except UnicodeDecodeError:
        pass

def convertFileWithDetection(fileName):
    print("Converting '" + fileName + "'...")
    format=get_encoding_type(fileName)
    try:
        with codecs.open(fileName, 'rU', format) as sourceFile:
            writeConversion(sourceFile)
            print('Done.')
            return
    except UnicodeDecodeError:
        pass

    print("Error: failed to convert '" + fileName + "'.")


def writeConversion(file):
    with codecs.open(outputDir + '/' + fileName, 'w', targetFormat) as targetFile:
        for line in file:
            targetFile.write(line)

# Off topic: get the file list and call convertFile on each file
# ...

(BEARBEITEN von Rudro Badhon: Dies beinhaltet die ursprünglichen Try-Multiple-Formate, bis Sie keine Ausnahme erhalten, sowie einen alternativen Ansatz, der chardet.universaldetector verwendet.)

13

Dies ist eine Python3 - Funktion zum Konvertieren einer beliebigen Textdatei in eine mit UTF-8-Kodierung. (ohne Verwendung unnötiger Pakete)

def correctSubtitleEncoding(filename, newFilename, encoding_from, encoding_to='UTF-8'):
    with open(filename, 'r', encoding=encoding_from) as fr:
        with open(newFilename, 'w', encoding=encoding_to) as fw:
            for line in fr:
                fw.write(line[:-1]+'\r\n')

Sie können es leicht in einer Schleife verwenden, um eine Liste von Dateien zu konvertieren.

1

Um die Quellcodierung zu erraten, können Sie den Befehl file * nix verwenden.

Beispiel:

$ file --mime jumper.xml

jumper.xml: application/xml; charset=utf-8
1
Ricardo

Dies ist meine Brute-Force-Methode. Es kümmert sich auch um das Mischen von\n und\r\n in der Eingabe.

    # open the CSV file
    inputfile = open(filelocation, 'rb')
    outputfile = open(outputfilelocation, 'w', encoding='utf-8')
    for line in inputfile:
        if line[-2:] == b'\r\n' or line[-2:] == b'\n\r':
            output = line[:-2].decode('utf-8', 'replace') + '\n'
        Elif line[-1:] == b'\r' or line[-1:] == b'\n':
            output = line[:-1].decode('utf-8', 'replace') + '\n'
        else:
            output = line.decode('utf-8', 'replace') + '\n'
        outputfile.write(output)
    outputfile.close()
except BaseException as error:
    cfg.log(self.outf, "Error(18): opening CSV-file " + filelocation + " failed: " + str(error))
    self.loadedwitherrors = 1
    return ([])
try:
    # open the CSV-file of this source table
    csvreader = csv.reader(open(outputfilelocation, "rU"), delimiter=delimitervalue, quoting=quotevalue, dialect=csv.Excel_tab)
except BaseException as error:
    cfg.log(self.outf, "Error(19): reading CSV-file " + filelocation + " failed: " + str(error))
0

Antwort für unbekannte Quellcodierungsart

basierend auf @ Sébastien RoccaSerra

python3.6

import os    
from chardet import detect

# get file encoding type
def get_encoding_type(file):
    with open(file, 'rb') as f:
        rawdata = f.read()
    return detect(rawdata)['encoding']

from_codec = get_encoding_type(srcfile)

# add try: except block for reliability
try: 
    with open(srcfile, 'r', encoding=from_codec) as f, open(trgfile, 'w', encoding='utf-8') as e:
        text = f.read() # for small files, for big use chunks
        e.write(text)

    os.remove(srcfile) # remove old encoding file
    os.rename(trgfile, srcfile) # rename new encoding
except UnicodeDecodeError:
    print('Decode Error')
except UnicodeEncodeError:
    print('Encode Error')
0
Sole Sensei