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
xgfan
V2EX  ›  Python

头痛的 python 编码问题

  •  
  •   xgfan · 2014-10-29 13:40:20 +08:00 · 5428 次点击
    这是一个创建于 3464 天前的主题,其中的信息可能已经有所发展或是发生改变。
    好吧,我知道这快成python的月经贴了。
    但是实在是搞不清楚……
    说说问题:
    python版本:python3.4
    Windows版本:8.1 x64
    代码:
    import requests
    a = '中文'
    print(a)
    b = requests.post("http://www.baidu.com/")
    print(b.encoding)
    print(b.text)
    --------------------------------
    当这六句代码无论是保存为utf-8,gbk,utf-8 with bom
    在cmd运行 python filename时,都是只能输出到b.encoding为utf-8
    然后b.text就报错 UnicodeEncodeError

    但是,在python的命令行模式中一行一行输入代码却可以正确运行。
    这问题到底是出在哪儿了?
    27 条回复    2014-10-30 23:26:09 +08:00
    RobberPhex
        1
    RobberPhex  
       2014-10-29 14:06:33 +08:00   ❤️ 1
    你应该用`b.content.decode('utf8')`的。
    首先,我抓包发现服务器没有返回编码信息,所以b.encoding不可信。
    然后,你必须手动指定解码方式,。
    unfurl
        2
    unfurl  
       2014-10-29 14:17:44 +08:00
    windows 环境是gbk编码
    3.X不熟悉,但是在2.X下,如果要在cmd下正常输入的话,得编码成gbk
    9hills
        4
    9hills  
       2014-10-29 14:27:50 +08:00
    首先第一条,不要在windows下使用Python
    geew
        5
    geew  
       2014-10-29 14:47:44 +08:00   ❤️ 1
    还是想说楼上的第一条: 不要在win下使用python

    这个我这里是没问题的 你试试
    https://gist.github.com/anonymous/dbf2a756317ea66ebb7c

    应该是3默认编码导致的
    b.text 在3下隐藏应该是 b.text.encode('gbk') # 而b.text由requests取得默认使用了utf8 decode然后就报错:
    UnicodeEncodeError: 'gbk' codec can't encode character '\xa1' in position 9908:
    illegal multibyte sequence
    猜的....

    总之别在win下用python
    fghzpqm
        6
    fghzpqm  
       2014-10-29 17:03:52 +08:00   ❤️ 2
    还好已经是用的 Python 3 了,否则会有一大堆人让你赶紧换 Python 3。

    好像不用 Windows 的各位没遇到过编码问题一样,遇到问题难道不应该弄明白原因,为什么看到这么多人莫名其妙的一会儿怪罪 Windows,一会儿怪罪 Python 2!

    这个问题的根本原因是 HTML 页面里的 '\xa1' 这个字符是在中文 Windows 终端默认编码 GBK 之外,所以 print 的时候将 .text(type 是 unicode)编码成 GBK 出错。

    楼主可以试试下面的代码:

    import requests
    resp = requests.post('http://www.baidu.com/')
    print(resp.encoding)
    print(resp.text.encode('gbk', 'ignore'))
    oaix
        7
    oaix  
       2014-10-29 17:19:58 +08:00
    @fghzpqm 赞同。遇到问题总是找借口绕过去。
    fghzpqm
        8
    fghzpqm  
       2014-10-29 17:20:26 +08:00
    好吧,吐槽别人发现自己也错了。

    原来楼主发起的是 POST 请求,会被重定向到另外一个页面,那个页面没有在 Content-Type header 里返回编码信息:

    $ curl -sI http://www.baidu.com/search/error.html | grep 'Content-Type'
    Content-Type: text/html

    这种时候 requests 使用 ISO-8859-1 作为默认编码。

    http://docs.python-requests.org/en/latest/user/advanced/#encodings

    .text 属性在弄错编码的情况下当然是错误的,我们需要显示的指定一下编码,下面才是正确的程序:

    import requests
    resp = requests.post('http://www.baidu.com/')
    resp.encoding = 'utf-8'
    print(resp.text.encode('gbk', 'ignore'))
    v2014
        9
    v2014  
       2014-10-29 18:15:04 +08:00
    cmd编码问题
    chcp 可以看到当前的编码,
    chcp 65001 这是把它改为 utf8的编码
    xgfan
        10
    xgfan  
    OP
       2014-10-29 18:35:04 +08:00
    @RobberPhex 指定编码也是同样的错误。

    @geew @fghzpqm 我这边问题挺奇葩的。指定resp.text.encode('utf-8')能正常运行,但是是类似于\xc2\xa2\xc3\xa6\xc2\x9f\xc2\xa5\xc3的字符串,指定resp.text.encode('gbk')则依旧报错……

    最怪异的是,这些错误都是建立在,保存好.py文件,在cmd以python filename 运行才会出错,如果在idle直接按条输入运行不会出错,在idle编辑好按F5执行也不会出错。
    我就有点怀疑是不是我本机的什么设置有误了。
    xgfan
        11
    xgfan  
    OP
       2014-10-29 18:46:12 +08:00
    现在又排除我的问题了,因为我在纯净虚拟机中跑也是同样的结果。
    mhycy
        12
    mhycy  
       2014-10-29 19:28:01 +08:00
    文件头声明编码
    字符串先decode再encode

    在python中这一直都是收到数据后的标准做法....
    除非库本身进行了这方面的处理
    mhycy
        13
    mhycy  
       2014-10-29 19:28:54 +08:00   ❤️ 1
    #coding=utf-8

    import sys
    import requests

    reload(sys)
    sys.setdefaultencoding('utf-8')

    req = requests.post('http://www.baidu.com')
    print req.text.decode('utf-8').encode('utf-8')


    最终输出UTF-8字符串...
    python 2.7环境下调试通过
    xgfan
        14
    xgfan  
    OP
       2014-10-29 19:32:42 +08:00
    @mhycy 可能是2.7和3.4有所不同,在3.4中,req.text已经是str了。
    错误信息:
    -- print(req.text.decode('utf-8').encode('utf-8'))
    AttributeError: 'str' object has no attribute 'decode'
    guotie
        15
    guotie  
       2014-10-29 19:40:16 +08:00
    自从用了golang以后,再也没有编码的问题
    mhycy
        16
    mhycy  
       2014-10-29 19:50:52 +08:00
    @xgfan 把输出重定向到文本文件看看
    chevalier
        17
    chevalier  
       2014-10-29 20:04:40 +08:00
    首先第一条,不要在windows下使用Python + 1
    DiffView
        18
    DiffView  
       2014-10-29 20:11:37 +08:00
    不要在windows下使用Python + 1 !!!
    "".encode "".decode
    reload(sys)
    sys.setdefaultencoding('utf-8')
    codec
    chcp

    这些就算你都会了,也不见得第三方库能正常用!!!!

    windows + python 简直就是作死,但是我还是不得不死 T.T
    est
        19
    est  
       2014-10-29 21:10:39 +08:00
    python编码有啥头痛的,我在cmd里直接输入个print就能抛出异常。
    momou
        20
    momou  
       2014-10-29 23:44:51 +08:00
    看了楼上各位说的,默默地开始下Ubuntu...
    geew
        21
    geew  
       2014-10-30 00:09:45 +08:00
    不要在windows下使用Python!!!!!!!!!!!!!!!!
    这个帖子该结了

    都散了吧
    xgfan
        22
    xgfan  
    OP
       2014-10-30 00:37:46 +08:00
    @geew 我主要是用python写点小工具,专门换个系统不划算,现在的解决方案就是,用idle编辑,然后在idle中运行,一切正常。
    ipconfiger
        23
    ipconfiger  
       2014-10-30 00:45:44 +08:00
    开发就不应该用windows!
    xgfan
        24
    xgfan  
    OP
       2014-10-30 01:12:50 +08:00
    @ipconfiger 开发.net的呢(逃
    Sharuru
        25
    Sharuru  
       2014-10-30 02:38:25 +08:00 via iPhone
    哭哭QAQ 最近在写的一个Py3工具也碰到了编码问题,拉下来UTF8的文本保存,下一次再读就变成GB2312了…
    ipconfiger
        26
    ipconfiger  
       2014-10-30 10:04:12 +08:00
    @xgfan 那就不要开发.NET嘛,哈哈
    fghzpqm
        27
    fghzpqm  
       2014-10-30 23:26:09 +08:00   ❤️ 2
    @xgfan 你完整的复制这个代码试试,虽然我没有 Windows 机器,但是不应该出问题:

    import requests
    resp = requests.post('http://www.baidu.com/')
    resp.encoding = 'utf-8'
    print(resp.text.encode('gbk', 'ignore'))
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5144 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 03:47 · PVG 11:47 · LAX 20:47 · JFK 23:47
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.