V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
omg21
V2EX  ›  Python

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

  •  
  •   omg21 · 2017-03-17 21:08:08 +08:00 · 2259 次点击
    这是一个创建于 2815 天前的主题,其中的信息可能已经有所发展或是发生改变。
    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 才能显示呢?
    12 条回复    2017-03-20 18:54:37 +08:00
    omg21
        1
    omg21  
    OP
       2017-03-17 21:45:02 +08:00
    网站编码的确是 utf-8 ,因为我在后台发布带有“•”字符的信息也能正常显示,但是用上传操作的时候用 bt = bt.encode('gbk')就会报错
    omg21
        2
    omg21  
    OP
       2017-03-17 22:13:25 +08:00
    刚才从数据库里取出来字符串再做个测试,结果也是 utf-8 。
    flniu
        3
    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
        4
    omg21  
    OP
       2017-03-17 22:30:01 +08:00
    @flniu 刚才从数据库里取出字符串用 encoding 做了个测试,全都是 utf-8 ,话说应该是 unicode 才对啊。
    既然数据库中的是 utf-8 ,那上传时不需要再转码啊
    PythonAnswer
        5
    PythonAnswer  
       2017-03-17 22:57:36 +08:00
    全程 utf8 ,我用 py3 后就没出现过编码问题了。
    flniu
        6
    flniu  
       2017-03-17 23:00:36 +08:00
    htmlstr, htmltype = encoding(htmlstr)
    这句执行完, type(htmlstr) 应该是 str
    你从数据库取出来后, type 是什么?

    另外你的 encoding 函数,如果 4 种情况都出错,会走 pass ,不 return 结果。
    flniu
        7
    flniu  
       2017-03-17 23:01:52 +08:00
    识别字符编码可以考虑用 cchardet 。
    单机数据库选 sqlite 比 access 好,除非有特殊需要。
    omg21
        8
    omg21  
    OP
       2017-03-17 23:07:19 +08:00
    @flniu 你从数据库取出来后, type 是什么?
    这里的 type 就是 utf-8 ,数据库连接我用的 pypyodbc ,好像也没找到有需要设置编码的地方。
    omg21
        9
    omg21  
    OP
       2017-03-17 23:08:00 +08:00
    @flniu 要改的话,整个系统都要改,太花时间了。
    bxb100
        10
    bxb100  
       2017-03-17 23:40:10 +08:00 via Android
    py IO 显示是 unicode 吧
    carlonelong
        11
    carlonelong  
       2017-03-19 10:37:30 +08:00
    存储是用 UTF-8 ,显示是根据你终端的编码来的吧
    decode 的参数是现在的类型,都是转成 unicode
    感觉最好还是用 py3 , py2 编码太坑了
    weyou
        12
    weyou  
       2017-03-20 18:54:37 +08:00
    这段代码有点意思, decode 函数怎么会知道你输入的字串的编码? 如果这个字串的某些字符不再这个编码的范围内, decode 才会报错啊。 不同的 code page 都是可能有相同的编码的啊。换言之, 就算用了错误的 encoding type , decode 函数还是有可能不会报错的, 只是得到的字符串并不是你期望得到的。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2565 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 02:57 · PVG 10:57 · LAX 18:57 · JFK 21:57
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.