Как я могу проверить Python unicode строка, чтобы видеть, что это *на самом деле* является надлежащий Unicode?

Таким образом, у меня есть эта страница:

http://hub.iis.sinica.edu.tw/cytoHubba/

По-видимому, это - все виды испорченных, поскольку это декодируется правильно, но когда я пытаюсь сохранить его в пост-ГРЭС, я добираюсь:

DatabaseError: invalid byte sequence for encoding "UTF8": 0xedbdbf

База данных замолчала после этого и отказывается делать что-либо без отката, который будет немного трудно выпустить (длинная история). Существует ли способ для меня проверить, произойдет ли это, прежде чем он поразит базу данных? source.encode ("utf-8") работает без помехи, таким образом, я не уверен, что продолжается...

7
задан Stavros Korokithakis 15 August 2010 в 12:38
поделиться

4 ответа

В python 2.x есть ошибка, которая исправляется только в python 3.x. На самом деле, эта ошибка есть даже в iconv OS X (но не в glibc).

Вот что происходит:

Python 2.x не распознает суррогатные пары UTF8 [1] как недопустимые (а именно такой является ваша последовательность символов)

Это должно быть все, что нужно:

foo.decode('utf8').encode('utf8')

Но благодаря ошибке, которую они не исправляют, он не перехватывает суррогатные пары.

Попробуйте сделать это в python 2.x, а затем в 3.x:

b'\xed\xbd\xbf'.decode('utf8')

В последнем случае он выдаст ошибку (правильно). Они не исправляют это и в ветке 2.x. Смотрите [2] и [3] для дополнительной информации

[1] http://tools.ietf.org/html/rfc3629#section-4

[2] http://bugs.python.org/issue9133

[3] http://bugs.python.org/issue8271#msg102209

9
ответ дан 7 December 2019 в 01:14
поделиться

Что именно вы делаете? Содержимое действительно декодируется как utf-8:

>>> import urllib
>>> webcontent = urllib.urlopen("http://hub.iis.sinica.edu.tw/cytoHubba/").read()
>>> unicodecontent = webcontent.decode("utf-8")
>>> type(webcontent)
<type 'str'>
>>> type(unicodecontent)
<type 'unicode'>
>>> type(unicodecontent.encode("utf-8"))
<type 'str'>

Убедитесь, что вы понимаете разницу между строками Unicode и строками в кодировке utf-8. То, что вам нужно отправить в базу данных, это unicodecontent.encode("utf-8") (это то же самое, что webcontent, но вы декодировали, чтобы проверить, что у вас нет недопустимых последовательностей байт в вашем источнике).

Я бы действительно, как говорит WoLpH, проверил настройки базы данных и соединения с базой данных.

0
ответ дан 7 December 2019 в 01:14
поделиться

Объект Python unicode - это последовательность кодовых точек Юникода и по определению правильный Юникод. Строка python str - это последовательность байтов, которые могут быть символами Unicode, закодированными в определенной кодировке (UTF-8, Latin-1, Big5,...).

Первый вопрос здесь - является ли source объектом unicode или str строкой. То, что source.encode("utf-8") работает, означает, что вы можете преобразовать source в строку с кодировкой UTF-8, но делаете ли вы это до передачи в функцию базы данных? Похоже, что база данных ожидает, что ее входные данные будут закодированы в UTF-8, и жалуется, что эквивалент source.decode("utf-8") не работает.

Если source является объектом unicode, он должен быть закодирован в UTF-8, прежде чем вы передадите его базе данных:

source = u'abc'
call_db(source.encode('utf-8'))

Если source является str, закодированным не в Utf-8, вы должны декодировать эту кодировку, а затем закодировать полученный объект Unicode в UTF-8:

source = 'abc'
call_db(source.decode('Big5').encode('utf-8'))
1
ответ дан 7 December 2019 в 01:14
поделиться

В конце концов, я решил просто обойти это, отловить ошибку и откатить транзакцию с помощью управления транзакциями Django. Я не понимаю, почему это могло произойти, хотя ...

0
ответ дан 7 December 2019 в 01:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: