Python: обрабатывает поврежденные байты юникода при разборе строки JSON

#python #json #unicode

#python #json #юникод

Вопрос:

Мой код делает получение некоторого содержимого с сайта пользовательского голоса. Как вы, возможно, знаете, UserVoice — дерьмовая программа, которая не может правильно обрабатывать данные; действительно, чтобы уменьшить объем текста на странице поиска, они сокращают текст, скажем, до 300 символов, а затем добавляют «…» в конец. Дело в том, что им все равно вырезать середину многобайтового символа, что приводит к частичному utf-8 «байту»: например. для è символа я получил xc3 вместо xc3xa8s .

Конечно, когда я даю этот ужасный суп json.loads , он терпит неудачу UnicodeDecodeError . Итак, мой вопрос прост: как я могу попросить json.loads игнорировать эти плохие байты, как я бы сделал .decode('utf-8', 'ignore') , если бы у меня был доступ к внутренним функциям функции?

Спасибо.

Ответ №1:

Вы не просите simplejson игнорировать их. Когда у меня возникла аналогичная проблема, подобная вашей, я просто запустил .decode('utf-8', 'ignore').encode('utf-8') и продолжил.

Комментарии:

1. Хорошо, в настоящее время я писал ответ, в котором говорилось, что я могу просто декодировать строку перед ее передачей json.loads . Спасибо, это, очевидно, работает!

Ответ №2:

Просто передайте строку Юникода в json.loads() :

 >>> badstr = "qualité"[:-1] ".."
>>> badstr
'qualitxc3..'
>>> json_str = '["%s"]' % badstr
>>> import json
>>> json.loads(json_str)
Traceback (most recent call last):
 ...
UnicodeDecodeError: 'utf8' codec can't decode byte 0xc3 in position 6: invalid 
continuation byte
>>> json.loads(json_str.decode('utf-8','ignore'))
[u'qualit..']
  

Комментарии:

1. Ответ от @Lucho включает дополнительный .encode , нужен ли он?

2. @Matteo: формат no. json определен для текста в Юникоде и, следовательно .encode() , после .decode() не требуется.