Seite 1 von 1
VErarbeiten von CSV in UTF-8: UnicodeEncodeError
Verfasst: Freitag 7. Dezember 2018, 14:01
von Daniel26
Hallo,
ich bastle jetzt schon seit heute morgen an einem Problem, aber ich kriegs irgendwie nicht gebacken.....
Ich hab eine CSV-Datei aus 3 Spalten, getrennt durch Semicolon, in UTF-8. Die Felder können Umlaute oder sonstiges enthalten (sollte ja bei UTF-8 kein Ding sein).
Das ganze unter Python 3.5.3.
Die CSV hat momentan folgenden Inhalt:
Code: Alles auswählen
zeile 1;aeiouäöü;ÖÖÖÖÄÄÄÄÄÜÜÜÜ;
Zeile 2;ÖÖÖÖÄÄÄÄÄÜÜÜÜ;aeiouäöü;
ICh mache das wie folgt auf:
Code: Alles auswählen
>>> with open("test.csv",'rU',encoding='utf-8') as csvfile:
... xxx=csv.reader(csvfile, delimiter=';', quotechar='"')
... for row in xxx:
... print(row[0])
... print(row[1])
...
zeile 1
Traceback (most recent call last):
File "<stdin>", line 5, in <module>
UnicodeEncodeError: 'ascii' codec can't encode characters in position 5-7: ordinal not in range(128)
Tja, jetzt die Preisfrage: Warum? Da ist nichts drin, was nicht durch UTF-8 abgedeckt wäre....
Hab ich da irgendwo ein Verständnisproblem?
Gruß
Daniel
Re: VErarbeiten von CSV in UTF-8: UnicodeEncodeError
Verfasst: Freitag 7. Dezember 2018, 14:34
von __deets__
Du hast ein Verständnisproblem. Schau mal genau auf die Zeilennummer, und wie GENAU die Ausnahme heißt.
Re: VErarbeiten von CSV in UTF-8: UnicodeEncodeError
Verfasst: Freitag 7. Dezember 2018, 15:08
von Daniel26
Hallo,
dann steh ich auf dem Schlauch. Stolpert er über das Leerzeichen?
Das hab ich auch mal raus und durch nen Unterstrich ersetzt....
Code: Alles auswählen
Python 3.5.3 (default, Sep 27 2018, 17:25:39)
[GCC 6.3.0 20170516] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import csv
>>> with open("test.csv",'rU') as csvfile:
... xxx=csv.reader(csvfile, delimiter=';', quotechar='"')
... for row in xxx:
... print(row[0])
... print(row[1])
...
Traceback (most recent call last):
File "<stdin>", line 3, in <module>
File "/usr/lib/python3.5/encodings/ascii.py", line 26, in decode
return codecs.ascii_decode(input, self.errors)[0]
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 13: ordinal not in range(128)
Gruß
Daniel
Re: VErarbeiten von CSV in UTF-8: UnicodeEncodeError
Verfasst: Freitag 7. Dezember 2018, 15:15
von __deets__
Dein Problem entsteht beim PRINT. Nicht beim einlesen. Und du hast ein ENCODING-Problem, also der Versuch, unicode (das du im Python-Interpreter hast) auszugeben. Dazu muss das ENKODIERT werden, und warum auch immer deine Terminal oder IDE-Settings das verbocken, aber da will Python ascii verwenden. Du musst also die Einstellungen deiner Umgebung da so aendern, dass Python inferieren kann, welches Encoding zB dein Terminal verwendet. Oder wie auch immer deine IDE das macht. Oder (testweise mindestens) mal einfach "row[0].encode('utf-8')" benutzen.
Re: VErarbeiten von CSV in UTF-8: UnicodeEncodeError
Verfasst: Freitag 7. Dezember 2018, 15:31
von __deets__
Nachtrag: meine Anmerkung bezog sich auf deinen ersten Post. Im zweiten Post hast du ja das utf-8 entfernt aus dem einlesen, das ist dan DEKODIEREN, und geht natuerlich in die Hose.
Re: VErarbeiten von CSV in UTF-8: UnicodeEncodeError
Verfasst: Freitag 7. Dezember 2018, 15:45
von Daniel26
Jo, danke, Groschen gefallen.
Ich hab das ganze im Xterm aufgeufen, das kann kein UTF-8. Im Uxterm gehts.
Das stellt mich dann vor die Aufgabe das ganze zur jeweiligen Umgebung passend kodiert auszugeben....
Danke soweit mal.
Gruß
Daniel
Re: VErarbeiten von CSV in UTF-8: UnicodeEncodeError
Verfasst: Freitag 7. Dezember 2018, 15:58
von __deets__
Fuer print/sys.stdout sollte Python das normalerweise selbst rausfinden. Wenn du selber Dateien speicherst, dann ist das immer deine Aufgabe, ja. Nur du kannst wissen, welches Format zur Weitergabe geeignet ist.
Re: VErarbeiten von CSV in UTF-8: UnicodeEncodeError
Verfasst: Freitag 7. Dezember 2018, 16:11
von Daniel26
Die Datei wird nur eingelesen und Teile davon wieder auf Stdout ausgegeben.
Wie krieg ich das Encoding der Umgebung am besten raus? sys.stdout.getencoding?
Und dann vor der Ausgabne mit irgendwas.encode(sys.stdout.getencoding)?
Oder gibts eleganteres?
Gruß
Daniel
Re: VErarbeiten von CSV in UTF-8: UnicodeEncodeError
Verfasst: Freitag 7. Dezember 2018, 16:26
von __deets__
Wenn du print benutzt, dann wird das doch implizit fuer dich gemacht. Was willst du da also selbst tun?
Re: VErarbeiten von CSV in UTF-8: UnicodeEncodeError
Verfasst: Freitag 7. Dezember 2018, 16:28
von Daniel26
Ich lese UTF-8 ein und gebs mit Print aus. Nun ruft halt nicht jedes das Programm in ner UTF-8-Umgebung.
Somit brichts dann mit obigem Fehler ab.
Oder was kann ich anders machen damit mir das nicht passiert?
Wenn da ein paar unlesbare Zeichen stehen ists egal, es sollte nur nicht abbrechen.
Gruß
Daniel
Re: VErarbeiten von CSV in UTF-8: UnicodeEncodeError
Verfasst: Freitag 7. Dezember 2018, 16:39
von snafu
Die
encode()-Methode hat einen
error-Parameter mit dem man das Verhalten im Falle von nicht darstellbaren Zeichen bestimmen kann:
Dies kannst du jetzt mit dem Encoding des Ausgabe-Streams kombinieren:
Re: VErarbeiten von CSV in UTF-8: UnicodeEncodeError
Verfasst: Freitag 7. Dezember 2018, 16:47
von Daniel26
Danke, jetzt bricht er schon mal nicht ab.
Aber wie krieg ich das "b" noch vor der Ausgabe weg?
Re: VErarbeiten von CSV in UTF-8: UnicodeEncodeError
Verfasst: Freitag 7. Dezember 2018, 17:29
von snafu
Das wird etwas komplizierter, sollte aber so klappen:
Code: Alles auswählen
import io
import sys
stdout = io.TextIOWrapper(sys.stdout.buffer, encoding=sys.stdout.encoding, errors='replace')
print(text, file=stdout)
Möglicherweise gibt es eine schönere Lösung, aber mir fiel nur diese ein.
In Python 3.7 wäre es ein simples:
... aber das nutzt da ja nicht und bringt dir somit nichts.
Re: VErarbeiten von CSV in UTF-8: UnicodeEncodeError
Verfasst: Sonntag 9. Dezember 2018, 16:17
von Daniel26
Danke, werds versuchen.
Gruß
Daniel
Re: VErarbeiten von CSV in UTF-8: UnicodeEncodeError
Verfasst: Sonntag 9. Dezember 2018, 18:10
von snafu
Oder du schreibst die Bytes direkt in
stdout:
Code: Alles auswählen
encoded = text.encode(sys.stdout.encoding, errors='replace')
sys.stdout.buffer.write(encoded + b'\n')