it-swarm.com.de

UnicodeDecodeError: Codec 'utf8' kann an Position 3-6 keine Bytes decodieren: ungültige Daten

wie funktioniert das Unicode-Ding auf Python2? Ich verstehe es einfach nicht.

hier lade ich Daten von einem Server herunter und analysiere sie für JSON.

Traceback (most recent call last):
  File "/usr/local/lib/python2.6/dist-packages/eventlet-0.9.12-py2.6.Egg/eventlet/hubs/poll.py", line 92, in wait
    readers.get(fileno, noop).cb(fileno)
  File "/usr/local/lib/python2.6/dist-packages/eventlet-0.9.12-py2.6.Egg/eventlet/greenthread.py", line 202, in main
    result = function(*args, **kwargs)
  File "Android_suggest.py", line 60, in fetch
    suggestions = suggest(chars)
  File "Android_suggest.py", line 28, in suggest
    return [i['s'] for i in json.loads(opener.open('https://market.Android.com/suggest/SuggRequest?json=1&query='+s+'&hl=de&gl=DE').read())]
  File "/usr/lib/python2.6/json/__init__.py", line 307, in loads
    return _default_decoder.decode(s)
  File "/usr/lib/python2.6/json/decoder.py", line 319, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/lib/python2.6/json/decoder.py", line 336, in raw_decode
    obj, end = self._scanner.iterscan(s, **kw).next()
  File "/usr/lib/python2.6/json/scanner.py", line 55, in iterscan
    rval, next_pos = action(m, context)
  File "/usr/lib/python2.6/json/decoder.py", line 217, in JSONArray
    value, end = iterscan(s, idx=end, context=context).next()
  File "/usr/lib/python2.6/json/scanner.py", line 55, in iterscan
    rval, next_pos = action(m, context)
  File "/usr/lib/python2.6/json/decoder.py", line 183, in JSONObject
    value, end = iterscan(s, idx=end, context=context).next()
  File "/usr/lib/python2.6/json/scanner.py", line 55, in iterscan
    rval, next_pos = action(m, context)
  File "/usr/lib/python2.6/json/decoder.py", line 155, in JSONString
    return scanstring(match.string, match.end(), encoding, strict)
UnicodeDecodeError: 'utf8' codec can't decode bytes in position 3-6: invalid data

danke dir!!

BEARBEITEN: Die folgende Zeichenfolge verursacht den Fehler: '[{"t":"q","s":"abh\xf6ren"}]'. \xf6 sollte zu ö dekodiert werden (abhören)

51
ihucos

Die Zeichenfolge, die Sie als JSON analysieren möchten, ist nicht in UTF-8 codiert. Höchstwahrscheinlich ist es in ISO-8859-1 kodiert. Versuche Folgendes:

json.loads(unicode(opener.open(...), "ISO-8859-1"))

Damit werden alle Umlaute behandelt, die möglicherweise in der JSON-Nachricht enthalten sind.

Du solltest Joel Spolskys das absolute Minimum lesen, das jeder Softwareentwickler unbedingt und positiv wissen muss, muss etwas über Unicode und Zeichensätze wissen (keine Ausreden!) . Ich hoffe, dass damit einige Probleme in Bezug auf Unicode geklärt werden.

Meine Lösung ist ein bisschen komisch. Ich hätte nie gedacht, dass das so einfach wäre wie das Speichern mit dem UTF-8-Codec. Ich verwende Notepad ++ (v5.6.8). Ich habe nicht bemerkt, dass ich es zunächst mit ANSI-Codec gespeichert habe. Ich verwende eine separate Datei, um das lokalisierte Wörterbuch zu platzieren. Ich habe meine Lösung unter der Registerkarte "Kodierung" in Notepad ++ gefunden. Ich wähle "Kodierung in UTF-8 ohne Stückliste" und speichere sie. Es funktioniert hervorragend.

6
rolypoly

Der Fehler, den Sie sehen, bedeutet, dass die Daten, die Sie vom Remote-End erhalten, kein gültiger JSON sind. JSON (gemäß der Spezifikation) ist normalerweise UTF-8, kann jedoch auch UTF-16 oder UTF-32 (entweder im Big- oder im Little-Endian-Format) sein. Der genaue Fehler bedeutet, dass ein Teil der Daten nicht vorhanden war gültiges UTF-8 (und auch nicht UTF-16 oder UTF-32, da dies zu unterschiedlichen Fehlern führen würde.)

Vielleicht sollten Sie die tatsächliche Antwort prüfen, die Sie von der Gegenseite erhalten, anstatt die Daten blind an json.loads() zu übergeben. Im Moment lesen Sie alle Daten aus der Antwort in eine Zeichenfolge und gehen davon aus, dass es sich um JSON handelt. Überprüfen Sie stattdessen den Inhaltstyp der Antwort. Stellen Sie sicher, dass die Webseite tatsächlich behauptet, Ihnen JSON zu geben, und nicht beispielsweise eine Fehlermeldung, dass nicht JSON ist.

(Verwenden Sie nach Überprüfung der Antwort json.load(), indem Sie das von opener.open() zurückgegebene dateiartige Objekt übergeben, anstatt alle Daten in einen String zu lesen und an json.loads() zu übergeben.)

4
Thomas Wouters

Die Lösung zum Ändern der Kodierung in Latin1/ISO-8859-1 löst ein Problem, das ich mit html2text.py festgestellt habe, als es bei einer Ausgabe von tex4ht aufgerufen wurde. Ich verwende das für eine automatisierte Word-Zählung in LaTeX-Dokumenten: tex4ht konvertiert sie in HTML und html2text.py bereinigt sie dann in reinen Text, um sie durch wc -w weiter zu zählen. Wenn nun beispielsweise ein deutscher "Umlaut" durch einen Eintrag in die Literaturdatenbank kommt, würde dieser Vorgang fehlschlagen, da sich html2text.py z.

UnicodeDecodeError: 'utf8'-Codec kann an Position 32243-32245 keine Bytes decodieren: ungültige Daten

Nun sind diese Fehler dann besonders schwer zu finden und Sie möchten im Wesentlichen den Umlaut in Ihrem Referenzbereich. Eine einfache Änderung in html2text.py aus

data = data.decode (Kodierung)

zu

data = data.decode ("ISO-8859-1")

löst dieses Problem; Wenn Sie das Skript mit der HTML-Datei als ersten Parameter aufrufen, können Sie die Kodierung auch als zweiten Parameter übergeben und die Änderung übernehmen.

3
Matthias Nott

Fügen Sie dies in Ihre Befehlszeile ein:

export LC_CTYPE="en_US.UTF-8" 
1
Mark Francis

Nur für jemanden hat das gleiche Problem. Ich benutze vim mit YouCompleteMe und konnte ycmd nicht mit dieser Fehlermeldung starten. Was ich getan habe, ist: export LC_CTYPE="en_US.UTF-8", das Problem ist weg.

1
hylepo

Teilen Sie in Ihrem Android_suggest.py diese monströse 1-Liner-Return-Anweisung in one_step_at_a_time-Teile auf. Protokollieren Sie repr(string_passed_to_json.loads) irgendwo, damit nach einer Ausnahmebedingung geprüft werden kann. Eye-Ball die Ergebnisse. Wenn das Problem nicht offensichtlich ist, bearbeiten Sie Ihre Frage, um den Repräsentanten anzuzeigen.

0
John Machin

Temporäre Problemumgehung: unicode(urllib2.urlopen(url).read(), 'utf8') - dies sollte funktionieren , wenn UTF-8 zurückgegeben wird.

urlopen().read() gibt Bytes zurück und Sie müssen sie zu Unicode-Strings dekodieren. Es wäre auch hilfreich, den Patch unter http://bugs.python.org/issue4733 zu überprüfen.

0
sorin