所以我有这个页面:
http://hub.iis.sinica.edu.tw/cytoHubba/
显然它是各种各样的混乱,因为它被正确解码但是当我尝试将它保存在postgres中时我得到:
DatabaseError: invalid byte sequence for encoding "UTF8": 0xedbdbf
数据库在此之后吵了起来并拒绝做任何事情而没有回滚,这将有点难以发布(长篇故事)。有没有办法让我检查一下它是否会在它到达数据库之前发生? source.encode(“utf-8”)顺利运行,所以我不确定发生了什么......
答案 0 :(得分:9)
python 2.x中有一个 bug ,它只是固定的python 3.x.实际上,这个bug甚至出现在OS X的iconv中(但不是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
答案 1 :(得分:1)
Python unicode
对象是一系列Unicode代码点,根据定义是正确的unicode。 python str
字符串是一个字节序列,可能是使用特定编码(UTF-8,Latin-1,Big5,...)编码的Unicode字符。
第一个问题是,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'))
答案 2 :(得分:0)
你究竟在做什么?内容确实解码为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所说,检查数据库和数据库连接的设置。
答案 3 :(得分:0)
最后,我选择了解决这个问题,捕获错误并使用Django的事务管理回滚事务。尽管如此......我为什么会发生这件事我感到很困惑。
答案 4 :(得分:0)
为了解决我与django / postgres的类似问题,我现在做这样的事情
class SafeTextField(models.TextField)
def get_prep_value(self, value):
encoded = base64.encodestring(value).strip()
return super(SafeTextField, self).get_prep_value(encoded)
def to_python(self, value):
decoded = base64.decodestring(value)
return super(SafeTextField, self).to_python(decoded)