Ich habe einen Socket-Server, der UTF-8-gültige Zeichen von Clients erhalten soll.
Das Problem ist, dass einige Clients (hauptsächlich Hacker) alle falschen Daten über sie senden.
Ich kann den echten Client leicht unterscheiden, aber ich protokolliere alle gesendeten Daten in Dateien, damit ich sie später analysieren kann.
Manchmal bekomme ich Zeichen wie diesen œ
, die den UnicodeDecodeError
-Fehler verursachen.
Ich muss in der Lage sein, den String UTF-8 mit oder ohne diese Zeichen zu erstellen.
Update:
Für meinen speziellen Fall war der Socket-Service ein MTA und daher erwarte ich nur ASCII Befehle wie:
EHLO example.com
MAIL FROM: <[email protected]>
...
Ich protokollierte das alles in JSON.
Dann beschlossen einige Leute ohne guten Vorsatz, Junk aller Art zu verkaufen.
Aus diesem Grund ist es in meinem speziellen Fall völlig in Ordnung, die NichtASCII Zeichen zu entfernen.
http://docs.python.org/howto/unicode.html#the-unicode-type
str = unicode(str, errors='replace')
oder
str = unicode(str, errors='ignore')
Hinweis: _ Hiermit werden die betreffenden Zeichen entfernt (ignoriert) und die Zeichenfolge ohne sie zurückgegeben.
Dies ist für mich ein idealer Fall, da ich es als Schutz vor Nicht-ASCII-Eingaben verwende, was in meiner Anwendung nicht zulässig ist.
Alternativ: Verwenden Sie die offene Methode aus dem Modul codecs
, um die Datei einzulesen:
import codecs
with codecs.open(file_name, "r",encoding='utf-8', errors='ignore') as fdata:
Diese Art von Problem taucht für mich auf, nachdem ich zu Python 3 gewechselt bin. Ich hatte keine Ahnung, dass Python 2 einfach Probleme mit der Dateicodierung hatte.
Ich fand diese nette Erklärung der Unterschiede und wie man eine Lösung findet, nachdem keiner der oben genannten Punkte für mich funktioniert hat.
http://python-notes.curiousefficiency.org/de/latest/python3/text_file_processing.html
Um Python 3 so ähnlich wie möglich zu machen, verwenden Sie:
with open(filename, encoding="latin-1") as datafile:
# work on datafile here
Lesen Sie jedoch den Artikel, es gibt keine einheitliche Lösung.
Der Wechsel der Engine von C zu Python hat mir geholfen.
Motor ist C:
pd.read_csv(gdp_path, sep='\t', engine='c')
'utf-8' Codec kann das Byte 0x92 in Position 18 nicht decodieren: ungültiges Startbyte
Engine ist Python:
pd.read_csv(gdp_path, sep='\t', engine='python')
Keine Fehler für mich.
>>> '\x9c'.decode('cp1252')
u'\u0153'
>>> print '\x9c'.decode('cp1252')
œ
Ich hatte dasselbe Problem mit UnicodeDecodeError
und ich habe es mit dieser Zeile gelöst.
str = str.decode('unicode_escape').encode('utf-8')
Nur für jemanden hat das gleiche Problem. Ich benutze vim mit YouCompleteMe , konnte ycmd nicht mit dieser Fehlermeldung starten. Was ich getan habe, ist: export LC_CTYPE="en_US.UTF-8"
, das Problem ist verschwunden.
Was können Sie tun, wenn Sie eine Datei ändern müssen, die Codierung der Datei jedoch nicht kennen? Wenn Sie wissen, dass die Kodierung ASCII-kompatibel ist und Sie nur die Teile ASCII untersuchen oder ändern möchten, können Sie die Datei mit dem Surrogateescape-Fehlerhandler öffnen:
with open(fname, 'r', encoding="ascii", errors="surrogateescape") as f:
data = f.read()
das erste, Verwenden von get_encoding_type, um den Dateityp der Codierung zu ermitteln:
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']
die zweite, öffnen Sie die Dateien mit dem Typ:
open(current_file, 'r', encoding = get_encoding_type, errors='ignore')