关于编码的几个疑问,搞糊涂了。

2017-03-17 21:08:08 +08:00
 omg21
def encoding(dm):
>>types = ['utf-8','utf-16','gb2312','gbk']
>>for type in types:
>>>>try:
>>>>>>return dm.decode(type),type
>>>>except:
>>>>>>pass

htmlstr = urllib.request.urlopen(htmlstr).read()
htmlstr,htmltype = encoding(htmlstr)

这是从网上找的代码,是先取到页面代码,然后用 encoding 判断代码的编码,是用试错法,从几个编码里挨个试,如果不能转换就换下一个,直到找到为止。我在执行完这一步就把页面代码存入数据库了,但是直接上传到自己的网站上时显示乱码,必须用 btstr = btstr.encode('gbk')转成 gbk 才能正确显示内容,我的网站是 utf-8 编码,系统是 xp , python34 , sublime3 ,数据库是 access ,步骤就是这样。

我现在奇怪的是上面代码中 return dm.decode(type),type 这句到底起什么作用?
如果对方网站是 utf-8 编码,那么 dm.decode('utf-8')是解码成 unicode ?
把这个网页代码存入数据库时是什么编码?
为什么上传的时候必须要编码成 gbk 才能显示呢?
2251 次点击
所在节点    Python
12 条回复
omg21
2017-03-17 21:45:02 +08:00
网站编码的确是 utf-8 ,因为我在后台发布带有“•”字符的信息也能正常显示,但是用上传操作的时候用 bt = bt.encode('gbk')就会报错
omg21
2017-03-17 22:13:25 +08:00
刚才从数据库里取出来字符串再做个测试,结果也是 utf-8 。
flniu
2017-03-17 22:16:05 +08:00
首先明确两个概念:
* 字符串(string),在 Python 3 中是 'abc' 或 str()
* 字节流(binary),在 Python 3 中是 b'abc' 或 bytes()
然后记清:
* str.encode() -> bytes
* bytes.decode() -> str

urlopen().read() 返回 bytes
你的 encoding 函数是通过 try 的方式找到正确的编码,然后 decode 成 str 同时返回对应编码名

把 str 值存入数据库时,要看数据库对应字段数据类型,一般 driver 会自动处理。建议选择支持 Unicode 存储的数据类型。
你可以在数据库里查看存储的字符串值对不对。

最后就是从数据库里读出字符串在网站显示,一般网站框架会自动处理。
omg21
2017-03-17 22:30:01 +08:00
@flniu 刚才从数据库里取出字符串用 encoding 做了个测试,全都是 utf-8 ,话说应该是 unicode 才对啊。
既然数据库中的是 utf-8 ,那上传时不需要再转码啊
PythonAnswer
2017-03-17 22:57:36 +08:00
全程 utf8 ,我用 py3 后就没出现过编码问题了。
flniu
2017-03-17 23:00:36 +08:00
htmlstr, htmltype = encoding(htmlstr)
这句执行完, type(htmlstr) 应该是 str
你从数据库取出来后, type 是什么?

另外你的 encoding 函数,如果 4 种情况都出错,会走 pass ,不 return 结果。
flniu
2017-03-17 23:01:52 +08:00
识别字符编码可以考虑用 cchardet 。
单机数据库选 sqlite 比 access 好,除非有特殊需要。
omg21
2017-03-17 23:07:19 +08:00
@flniu 你从数据库取出来后, type 是什么?
这里的 type 就是 utf-8 ,数据库连接我用的 pypyodbc ,好像也没找到有需要设置编码的地方。
omg21
2017-03-17 23:08:00 +08:00
@flniu 要改的话,整个系统都要改,太花时间了。
bxb100
2017-03-17 23:40:10 +08:00
py IO 显示是 unicode 吧
carlonelong
2017-03-19 10:37:30 +08:00
存储是用 UTF-8 ,显示是根据你终端的编码来的吧
decode 的参数是现在的类型,都是转成 unicode
感觉最好还是用 py3 , py2 编码太坑了
weyou
2017-03-20 18:54:37 +08:00
这段代码有点意思, decode 函数怎么会知道你输入的字串的编码? 如果这个字串的某些字符不再这个编码的范围内, decode 才会报错啊。 不同的 code page 都是可能有相同的编码的啊。换言之, 就算用了错误的 encoding type , decode 函数还是有可能不会报错的, 只是得到的字符串并不是你期望得到的。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/348319

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX