Подтвердить что ты не робот

UnicodeDecodeError: кодек 'utf8' не может декодировать байты в позиции 3-6: неверные данные

как работает юникод на python2? я просто не понимаю.

здесь я загружаю данные с сервера и разбираю их для 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

Благодарю вас!

EDIT: следующая строка вызывает ошибку: '[{"t":"q","s":"abh\xf6ren"}]'. \xf6 должен быть декодирован до ö (абхорен)

4b9b3361

Ответ 1

Строка, которую вы пытаетесь разобрать как JSON, не кодируется в UTF-8. Скорее всего, он кодируется в ISO-8859-1. Попробуйте следующее:

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

Это будет обрабатывать любые умляуты, которые могут попадать в сообщение JSON.

Вы должны прочитать Joel Spolsky Абсолютный минимум Каждый разработчик программного обеспечения Абсолютно, положительно должен знать о Unicode и наборах символов (без отговорок!). Надеюсь, что это прояснит некоторые проблемы, которые возникают вокруг Unicode.

Ответ 2

Мое решение немного смешно. Я никогда не думал, что это будет так же просто, как и с кодеком UTF-8. Я использую notepad ++ (v5.6.8). Я не заметил, что я сохранил его с помощью ANSI кодек изначально. Я использую отдельный файл для размещения всего локализованного словаря. Я нашел свое решение под вкладкой "Кодирование" из моего Notepad ++. Я выбираю "Кодирование в UTF-8 без спецификации" и сохраняю его. Он работает блестяще.

Ответ 3

Ошибка, которую вы видите, означает, что данные, которые вы получаете с удаленного конца, недействительны JSON. JSON (согласно спецификации), как правило, UTF-8, но также может быть UTF-16 или UTF-32 (либо с большим, либо с маленьким шрифтом). Точная ошибка, которую вы видите, означает, что некоторая часть данных не была действительный UTF-8 (а также не был UTF-16 или UTF-32, поскольку они могут приводить к различным ошибкам.)

Возможно, вам следует изучить фактический ответ, который вы получаете с удаленного конца, вместо того, чтобы слепо передавать данные на json.loads(). Прямо сейчас вы читаете все данные из ответа в строку и предполагаете это JSON. Вместо этого проверьте тип содержимого ответа. Убедитесь, что веб-страница на самом деле требует предоставить вам JSON, а не, например, сообщение об ошибке, которое не является JSON.

(Кроме того, после проверки ответа используйте json.load(), передав ему файл-подобный объект, возвращенный opener.open(), вместо того, чтобы читать все данные в строку и передавать их на json.loads().)

Ответ 4

Решение об изменении кодировки в Latin1/ISO-8859-1 решает проблему, которую я наблюдал с помощью html2text.py, как вызывается на выходе tex4ht. Я использую это для автоматического подсчета слов на документах LaTeX: tex4ht преобразует их в HTML, а затем html2text.py разбивает их на чистый текст для дальнейшего подсчета через wc-w. Теперь, если, например, немецкий "Umlaut" приходит через запись в базе данных литературы, этот процесс завершится неудачно, поскольку html2text.py будет жаловаться, например.

UnicodeDecodeError: кодек 'utf8' не может декодировать байты в позиции 32243-32245: недопустимые данные

Теперь эти ошибки впоследствии будут особенно трудно отследить, и, по сути, вы хотите иметь Umlaut в своем разделе ссылок. Простое изменение внутри html2text.py из

data = data.decode(кодирование)

к

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

решает эту проблему; если вы вызываете script, используя файл HTML в качестве первого параметра, вы также можете передать кодировку в качестве второго параметра и избавить модификацию.

Ответ 5

Просто в случае, если у кого-то такая же проблема. Я использую vim с YouCompleteMe, не удалось запустить ycmd с этим сообщением об ошибке, что я сделал: export LC_CTYPE="en_US.UTF-8", проблема в том, что ушел.

Ответ 6

Вставьте это в свою командную строку:

export LC_CTYPE="en_US.UTF-8" 

Ответ 7

Временное обходное решение: unicode(urllib2.urlopen(url).read(), 'utf8') - это должно работать, если возвращаемое является UTF-8.

urlopen().read() вернуть байты, и вы должны декодировать их в строки unicode. Также было бы полезно проверить патч от http://bugs.python.org/issue4733

Ответ 8

В вашем android_suggest.py распакуйте этот чудовищный однострочный оператор возврата в one_step_at_a_time. Запишите repr(string_passed_to_json.loads) где-нибудь, чтобы он мог быть проверен после того, как произойдет исключение. Получите результаты. Если проблема не очевидна, отредактируйте свой вопрос, чтобы показать реестр.