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

被 python 的编码问题折腾死了

  •  
  •   Yourdaye · 2016-01-18 18:36:01 +08:00 · 6455 次点击
    这是一个创建于 3025 天前的主题,其中的信息可能已经有所发展或是发生改变。

    python2.7+ubuntu

    用 beautifusoup 来解析一个网页,死活都输出不了中文

    什么 encode,decode 试了个遍都不行啊

    折腾了一下午.....

    有过类似经验的 V 友们给点指导啊!

    第 1 条附言  ·  2016-01-19 09:33:05 +08:00
    采用了 @fy 的方法,问题已解决,感谢各位的方案
    第 2 条附言  ·  2016-01-20 14:31:27 +08:00
    2016.1.20 更新:
    改用 requests 之后依然会在某些情况下出现乱码,最后用下面的方法彻底解决了,多谢博主!

    http://sh3ll.me/2014/06/18/python-requests-encoding/
    50 条回复    2016-01-20 17:26:19 +08:00
    bakabie
        1
    bakabie  
       2016-01-18 19:10:31 +08:00 via Android
    检查下 ide 的编码设置是否正确。。。
    我之前也是这样,在 pycharm 上无法输出中文。。。结果发现是 pycharm 内置编码没设置正确
    flyer103
        2
    flyer103  
       2016-01-18 19:15:47 +08:00
    黑魔法:

    ```python
    import sys
    reload(sys)
    sys.setdefaultencoding('utf-8')
    ```
    yunying
        3
    yunying  
       2016-01-18 19:18:42 +08:00
    不谢:
    http://wklken.me/posts/2013/08/31/python-extra-coding-intro.html

    看完后并理解后你就会感谢我的了
    Yourdaye
        4
    Yourdaye  
    OP
       2016-01-18 19:26:36 +08:00
    @bakabie 我是现在 pycharm 上测试,然后再服务器上测试,都不行
    DuckJK
        5
    DuckJK  
       2016-01-18 19:27:55 +08:00
    windfarer
        6
    windfarer  
       2016-01-18 19:28:01 +08:00 via Android
    先看网页的编码是什么,再在代码里做相应 decode
    just1
        7
    just1  
       2016-01-18 19:38:01 +08:00 via Android   ❤️ 1
    encode('utf-8').decode('unicode-escape')
    送你神器
    zaishanfeng
        8
    zaishanfeng  
       2016-01-18 19:42:55 +08:00 via Android
    楼上的几个方法我都用过 还是有问题 目前遇到的最好的解决方法是 django 的 smart_str
    RqPS6rhmP3Nyn3Tm
        9
    RqPS6rhmP3Nyn3Tm  
       2016-01-18 19:57:38 +08:00
    为什么不用 Python 3 呢,原生支持 utf-8
    抓网页直接 decode('utf-8') 就好了
    leavic
        10
    leavic  
       2016-01-18 20:09:07 +08:00
    @Yourdaye pycharm 默认的 console encoding 是 UTF-8 ,而其他系统的的 console 不一定是这个,所以 console 输出的问题不是单纯靠编码能解决的。
    Yourdaye
        11
    Yourdaye  
    OP
       2016-01-18 21:15:19 +08:00
    @BXIA 2 和 3 的这个坑难道填不平了?
    Yourdaye
        12
    Yourdaye  
    OP
       2016-01-18 21:18:10 +08:00
    @zaishanfeng 可惜我用的是 flask
    lcj2class
        13
    lcj2class  
       2016-01-18 21:20:30 +08:00   ❤️ 1
    RqPS6rhmP3Nyn3Tm
        14
    RqPS6rhmP3Nyn3Tm  
       2016-01-18 21:20:51 +08:00
    @Yourdaye 没用过 2 ,不过现在都在慢慢迁移到 3 了,以后可能也不会填坑了吧
    crayhuang
        15
    crayhuang  
       2016-01-18 21:38:21 +08:00
    同样被折腾过,用了跟二楼一样的方法解决
    fy
        16
    fy  
       2016-01-18 22:04:16 +08:00   ❤️ 2
    1. 楼主你别用 urllib ,换 requests , resp.text 直接是 unicode , py2 py3 直接 print 都能看
    2. 上 Python3 , py2 我们别管了
    Victor215
        17
    Victor215  
       2016-01-18 22:25:17 +08:00
    用 requests + chardet, 爬虫包治百病!
    knightdf
        18
    knightdf  
       2016-01-18 22:40:39 +08:00
    全部用 unicode
    yaozeyuan93
        19
    yaozeyuan93  
       2016-01-18 22:42:09 +08:00
    先不用管 encode/decode 的事。

    在程序开始时将编码设成 utf-8

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

    代码里凡是涉及到字符串的,一律使用 u''字符串。

    对于外部输入,一律使用 decode 处理成 unicode 字符,确保程序内部是一个纯净的 unicode 字符环境

    输出时,视情况 encode 成 utf-8 的 bytes 或者直接输出(让 python 系统自行处理)。

    只要做到这些,一般就不会再碰见乱码问题了。

    创意来源: Pycon2012 演讲, Unicode 之痛。中文翻译: https://github.com/PyCodersCN/PyCodersCN/blob/6d0c0607dfa609c443eaea5904789cf833ebc679/issue5/unipain.rst

    我在自己的知乎助手( py2.7+urllib2+BS4 )里试了一下,很好用。目前为止还没有人向我反馈过乱码 bug
    weakiwi
        20
    weakiwi  
       2016-01-18 22:48:17 +08:00
    有时候是 ide 自己的问题,建议直接 linux 环境 nano
    ltm
        21
    ltm  
       2016-01-18 22:49:47 +08:00
    你需要 python3
    n6DD1A640
        22
    n6DD1A640  
       2016-01-18 22:53:25 +08:00
    反正能用 python 3 的地方我都用了。。
    jok3r
        23
    jok3r  
       2016-01-18 23:24:32 +08:00
    暑假折腾过一次,用 Python3 解决,后来再转 Python2 ,却又没问题了。
    前几天又折腾一次,折腾一晚上,结果发现网页开启了 gzip 压缩,需要先解压再解析。
    zaishanfeng
        24
    zaishanfeng  
       2016-01-18 23:47:16 +08:00 via Android
    @Yourdaye 这个只是一个函数 可以 import 直接导入就能用 试过很多方法 什么 reload 什么 requests 什么 encode 有的情况上面的可以解决 但是很多时候试遍了还是不行 只有 smart_str 百试百灵
    quietin
        25
    quietin  
       2016-01-18 23:48:17 +08:00
    nooper
        26
    nooper  
       2016-01-19 00:11:48 +08:00 via iPad
    py3
    Delbert
        27
    Delbert  
       2016-01-19 00:12:00 +08:00 via Android
    用 requests 输出文件编码。我曾接解析过一个繁体中文网页差点没折腾死我,后来发现是 ISO1xxxx 编码……
    fy
        28
    fy  
       2016-01-19 00:37:37 +08:00
    @Delbert requests 特定网页有一个问题,没记错的话是信任服务器反馈的 encoding 而不是 html 中指定的 encoding 。

    不过这个函数官方也写了,我不懂他们为啥不默认开启
    LINAICAI
        29
    LINAICAI  
       2016-01-19 02:01:58 +08:00
    还从来没遇到过编码问题没法解决的。。。别乱喷
    limbo0
        30
    limbo0  
       2016-01-19 03:53:07 +08:00
    方法是一律导成 unicode
    popil1987
        31
    popil1987  
       2016-01-19 08:53:17 +08:00
    由于你没有放出错误,所以说几处容易乱码的你参考一下。
    1.确定获取的内容是字符串吗?有可能是 gzip 压缩的
    2.用 chardet 检测获取内容的编码,或者存到文件中,用 file 命令查看文件编码
    3.获取的内容要 decode 成 unicode 才能输出
    4.存到文件要 encode 成某个编码
    laobaozi
        32
    laobaozi  
       2016-01-19 08:54:29 +08:00 via iPhone
    chardet +1
    另外我还遇见过抓取的网页有一部分在终端显示不全,还以为网页是由 js 生成的,直到我把抓取的内容写入文件....
    Hackathon
        33
    Hackathon  
       2016-01-19 08:56:57 +08:00
    ltype
        34
    ltype  
       2016-01-19 09:17:38 +08:00
    用 python3 啊
    zhuangzhuang1988
        35
    zhuangzhuang1988  
       2016-01-19 09:23:03 +08:00
    所以, 来学 c#吧..
    strahe
        36
    strahe  
       2016-01-19 09:35:30 +08:00
    python3 从来不考虑这些问题
    Yourdaye
        37
    Yourdaye  
    OP
       2016-01-19 09:47:21 +08:00
    @strahe 以后果断 python3,不知道 2 的坑还有多少
    caomaocao
        38
    caomaocao  
       2016-01-19 09:48:10 +08:00
    @Victor215 chardet 对短的文本 不一定判断对啊!
    zkzipoo
        39
    zkzipoo  
       2016-01-19 10:29:27 +08:00
    locale charmap
    #coding:utf-8
    怎么不把网页发过来
    zkzipoo
        40
    zkzipoo  
       2016-01-19 10:32:47 +08:00
    更正一下#coding=utf-8
    picasso250
        41
    picasso250  
       2016-01-19 11:05:55 +08:00
    请使用 PHP
    fhefh
        42
    fhefh  
       2016-01-19 11:41:45 +08:00
    学习了~~
    esile
        43
    esile  
       2016-01-19 12:20:36 +08:00 via iPhone
    @flyer103 必须这样玩
    XuanYuan
        44
    XuanYuan  
       2016-01-19 12:21:37 +08:00
    我也是,被 ruby 的编码问题折腾得够呛。

    问题是这样子的:
    我现在有一个 utf-8 编码的文本,但是需要把它转换成 ASCII 格式,比如说,原来的“生”字要转换成“\u751F ”。

    查了很多资料,还是一头雾水。
    MemoryCorner
        45
    MemoryCorner  
       2016-01-19 12:48:00 +08:00
    用 Python3, 用 Python3, 用 Python3, 早晚要用的。
    cxh116
        46
    cxh116  
       2016-01-19 15:19:09 +08:00   ❤️ 1
    @XuanYuan 这种在 python 里面叫 "unicode escape"

    ruby 可以参考这个 http://stackoverflow.com/questions/5560914/how-do-i-escape-a-unicode-string-with-ruby

    puts '你好'.unpack('U*').map{ |i| "\\u" + i.to_s(16).rjust(4, '0') }.join
    XuanYuan
        47
    XuanYuan  
       2016-01-20 15:03:09 +08:00
    @cxh116 已谢!
    我是初学,之前还想用 iconv 来解决未果。
    XuanYuan
        48
    XuanYuan  
       2016-01-20 15:09:10 +08:00
    @cxh116 如果只需要转一个句子里面的中文,这个正则应该加在什么地方呢?

    比如说,“我是 1 级 VIP ”中只转“我、是、级”。
    cxh116
        49
    cxh116  
       2016-01-20 15:55:03 +08:00   ❤️ 1
    @XuanYuan 用 gsub,自己把下面的正则替换成你自己想要的正则.

    puts '你好 123abc'.gsub(/[\W]/){|s| s.unpack('U*').map{|i| "\\u" + i.to_s(16).rjust(4, '0')}.join }

    正则可以参考这个
    http://apidock.com/rails/v3.0.5/ActiveSupport/JSON/Encoding/escape/class
    XuanYuan
        50
    XuanYuan  
       2016-01-20 17:26:19 +08:00
    收到,谢谢!
    我再好好学习一下。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   834 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 21:09 · PVG 05:09 · LAX 14:09 · JFK 17:09
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.