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

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
toom
User
Beiträge: 10
Registriert: Freitag 22. Mai 2009, 08:44

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]
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

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.
toom
User
Beiträge: 10
Registriert: Freitag 22. Mai 2009, 08:44

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?
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.
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

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]
BlackJack

@derdon: Er *muss* an dieser Stelle `unicode`-Objekte nehmen. Schau mal von welchem Typ `f` ist.
toom
User
Beiträge: 10
Registriert: Freitag 22. Mai 2009, 08:44

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.
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?
toom
User
Beiträge: 10
Registriert: Freitag 22. Mai 2009, 08:44

Wie "kläre" ich denn welche Bytewerte in der Datei stehen?
lunar

Schau dir die Datei in einem Hexeditor an.
toom
User
Beiträge: 10
Registriert: Freitag 22. Mai 2009, 08:44

Und was erkennt man dann, wenn man z.B. "0D 0A 0D 0A" liest?
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!
fhoech
User
Beiträge: 143
Registriert: Montag 9. April 2007, 18:26

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)
toom
User
Beiträge: 10
Registriert: Freitag 22. Mai 2009, 08:44

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?
Benutzeravatar
mosenturm
User
Beiträge: 23
Registriert: Dienstag 15. Juli 2008, 17:54
Wohnort: Plauen
Kontaktdaten:

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
Viele Grüße
Andreas
fhoech
User
Beiträge: 143
Registriert: Montag 9. April 2007, 18:26

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.
Antworten