Seite 1 von 1

"Western European (Mac Roman)"-kodierte Datei einl

Verfasst: Mittwoch 10. Juni 2009, 16:29
von toom
Ich möchte mehrere Dateien mit Python einlesen, die in "Western European (Mac Roman)" kodiert sind. Anschließend bearbeite ich die gelesenen Daten in einem Python-Skript und dann speichere alles in einer großen Datei. Das Problem: wenn ich die Dateien einlese, dann werden Umlaute nicht richtig kodiert und wenn ich die Daten dann abspeichere, erhalte ich natürlich eine "fehlerhafte" Datei.

Leider sind es so viele Dateien, dass ich diese nicht alle von Hand umkodieren kann.

Wie kann ich sicherstellen, dass Python diese Kodierung richtig einliest?[/quote]

Verfasst: Mittwoch 10. Juni 2009, 16:40
von cofi
Nicht Python macht den Fehler sondern du, denn wenn du eine exotische Kodierung (bei Python 2.x: alles ausser ASCII, Python 3: alles außer UTF-8) benutzt, musst du die angeben.

Schau dir mal http://docs.python.org/library/codecs.html an.

Verfasst: Mittwoch 10. Juni 2009, 19:05
von toom
Also ich mache jetzt folgendes

macroman-kodierte Datei einlesen mit der folgenden Methode:

Code: Alles auswählen

def readDataFromFile( filePath ):
    try:
        f = codecs.open( filePath, 'r', 'macroman' )
        data = unicode( f.read() )
        f.close()
        return data
    except IOError:
        print 'Fehler beim Lesen der Datei' + filePath
Und anschließend die Daten in die Datei schreiben mit folgender Methode:

Code: Alles auswählen

def writeCCDFsToFile( ccdfs ):
    try:
        f = codecs.open('/pfad/zur/Datei/data.txt','w','utf-8')
        for ccdf in ccdfs:
            f.write( unicode( ccdf.city + '^_^' + ccdf.description + '^_^' + ccdf.latlng + '\n') )
        f.close()
    except IOError:
        print 'Fehler beim Schreiben der ccdfs.'
Trotzdem werden Umlaute falsch kodiert.
In der Datei steht dann z.B. "fl" anstatt "ß", oder "‰" anstatt "ä". Was mache ich hier falsch?

Verfasst: Mittwoch 10. Juni 2009, 19:12
von BlackJack
In der Datei stehen keine Zeichen, sondern Bytes. Also solltest Du als erstes mal klären was für Bytes in den jeweiligen Dateien stehen.

Verfasst: Mittwoch 10. Juni 2009, 19:12
von derdon
Du kannst keine Unicode-Objekte in eine Datei schreiben. Unicode ist etwas Abstraktes, zum Schreiben solltest du Bytestrings nehmen. Für weitere Informationen: [wiki]Von Umlauten, Unicode und Encodings[/wiki]

Verfasst: Mittwoch 10. Juni 2009, 19:30
von BlackJack
@derdon: Er *muss* an dieser Stelle `unicode`-Objekte nehmen. Schau mal von welchem Typ `f` ist.

Verfasst: Mittwoch 10. Juni 2009, 19:34
von toom
Gut, ich habe mir den Link durchgelesen und habe meine Methode wie folgt geändert:

Code: Alles auswählen

def readDataFromFile( filePath ):
    try:
        f = codecs.open( filePath, 'r', 'macroman' )
        data = f.read().encode('utf-8')
        f.close()
        return data
    except IOError:
        print 'Fehler beim Lesen der Datei' + filePath

und

Code: Alles auswählen

def writeCCDFsToFile( ccdfs ):
    try:
        f = open('/pfad/zur/Datei/data.txt','w')
        for ccdf in ccdfs:
            f.write( ccdf.city + '^_^' + ccdf.description + '^_^' + ccdf.latlng + '\n')
        f.close()
    except IOError:
        print 'Fehler beim Schreiben der ccdfs.'
Bringt aber leider auch nix. Umlaute werden nach wie vor falsch gespeichert.

Verfasst: Mittwoch 10. Juni 2009, 23:24
von BlackJack
Dann musst Du sie halt richtig speichern. So einfach ist das.

Oder endlich mal mit mehr Informationen herausrücken, welche Bytewerte in den betroffenen Dateien stehen. Wie siehst Du, das am Ende falsche Bytes in der Ausgabedatei landen? Das Programm mit dem Du nachschaust verwendet auch ganz sicher UTF-8 zum dekodieren? Falls ja, wie sicher bist Du, das in der Eingabedatei MacRoman steht? Und was passiert dazwischen mit den Daten?

Verfasst: Freitag 12. Juni 2009, 12:52
von toom
Wie "kläre" ich denn welche Bytewerte in der Datei stehen?

Verfasst: Freitag 12. Juni 2009, 13:13
von lunar
Schau dir die Datei in einem Hexeditor an.

Verfasst: Freitag 12. Juni 2009, 14:50
von toom
Und was erkennt man dann, wenn man z.B. "0D 0A 0D 0A" liest?

Verfasst: Freitag 12. Juni 2009, 15:18
von lunar
Du kannst damit überprüfen, ob du die richtige Kodierung für die Dateien nutzt. Such dir eine Stelle, an der ein Sonderzeichen wie "ö" steht, und merke dir den Bytewert. Dann kannst du beispielsweise unter Wikipedia den Artikel über die vermutete Kodierung anschauen, und anhand der dort aufgeführten Zeichentabelle überprüfen, ob deine Vermutung (in diesem Fall "macroman") überhaupt korrekt war und die Dateien korrekt dekodiert wurden.

Vor allem aber solltest du bitte alle Fragen aus BlackJacks letztem Posting beantworten!

Verfasst: Freitag 12. Juni 2009, 15:32
von fhoech
Hex 0D 0A sind die Zeichen "Carriage Return" gefolgt von "Newline". Windows-Systeme verwenden diese Zeichenfolge als Zeilenumbruch.

BTW: Eventuell hilft es, wenn du die ursprüngliche Textdatei, die du verarbeiten möchtest, mal hochlädst, so dass man auch mal einen Blick reinwerfen kann. Könnte ja sein, dass diese garnicht MacRoman-codiert ist, sprich du von einer falschen Annahme ausgehst.

Außerdem würde ich die Datei nach dem Einlesen nicht direkt in ein anderes Encoding umwandeln:

Code: Alles auswählen

f = codecs.open( filePath, 'r', 'macroman' )
data = f.read()
gibt einen Unicode-String, was vorteilhaft ist wenn du die Daten noch weiterverarbeitest (dann aber auch im restlichen Programm konsequent mit Unicode-Strings arbeiten). Erst beim Schreiben machst du dann

Code: Alles auswählen

fo = codecs.open( 'ausgabe.txt', 'w', 'utf-8' )
fo.write(data)

Verfasst: Freitag 12. Juni 2009, 15:34
von toom
Okay ich habe z.B. für den Umlaut "ü" der als das Zeichen "¸" geschrieben wird die Hexdarstellung FC. In welcher Tabelle kann ich nun die Kodierung nachschauen?

Verfasst: Freitag 12. Juni 2009, 15:42
von mosenturm
toom hat geschrieben:Okay ich habe z.B. für den Umlaut "ü" der als das Zeichen "¸" geschrieben wird die Hexdarstellung FC. In welcher Tabelle kann ich nun die Kodierung nachschauen?
Das entspräche aber ISO 8859 (http://de.wikipedia.org/wiki/ISO_8859#B ... he_Sprache)

In macroman ist das das "ü" : 9F (http://de.wikipedia.org/wiki/MacRoman)

Gruß Andreas

Verfasst: Freitag 12. Juni 2009, 15:55
von fhoech
Achja: Um das Encoding einer Textdatei auf relativ einfache Weise herauszufinden, kann man sie z.B. im Firefox öffnen und dann im Menü unter Ansicht -> Zeichenkodierung schauen. Das klappt meiner Erfahrung nach recht gut, auch wenns nicht immer funktioniert (z.B. wenn die Datei Encodings "mixt" oder anderweitig fehlerhaft ist). Wenn bei vielen Dateien das Encoding nicht bekannt ist, ist dieser Weg aber sicher zu zeitaufwändig :)

*edit* ok, für MacRoman war das ein schlechter Vorschlag. Das wird von Firefox fälschlicherweise als Windows-1252 erkannt.