bevin 发表于 2014-11-25 22:00:29

python编码问题初探

本帖最后由 bevin 于 2014-11-25 22:07 编辑

由于最近很多鱼油碰到中文字符串的编码以及显示问题,现在列一个帖子说明一下


主要涉及到的因素:文件编码,python解析器版本,在IDLE下print语句和直接显示的输出差异

一、python 2.x

如果你用的是2.x版本的python,那么能在IDLE中正常输出的编码是ASCII ,GBK(GB2312),Unicode。如果你想在IDLE解释器中正常显示字符,那么编码必须是三者之一,另外python 2.x中默认的编码是GBK,即你在IDLE中输入的中文字符默认的编码是GBK。


如果你正在处理文件,并想文件中的中文能在IDLE正常显示,我们来看看应该怎么处理:

注意右下角的文件编码是GBK,此时我们读取文件内容并显示:


可以看到不需作任何处理,输出的内容是正常的。

下面看看当文件编码是UTF8时,IDLE的表现:

测试代码如下:



代码中,第一行的输出为直接print字符串,可以看到内容为乱码
第二行是用字符串的decode方法将字符串用UTF8解码成Unicode字符,此时字符串可以正常输出
第三行是将字符串解码后再用gbk编码,此时字符串亦能正常输出

Tips:
1.在不改变IDLE的环境设置时,IDLE中的汉字的编码默认都是GBK。
2.不要把IDLE中的字符串和从文件中读取的字符串放在同一个print语句中混合输出。
3.py代码中中文字符的编码和py文件的编码一致,即源文件编码是GBK,那么其中汉字的编码为GBK,源文件编码是UTF8,那么其中汉字的编码为UTF8

下面在来说一下在python2.x中输出的一个很奇怪的现象,如下图:

在IDLE中,a是一个中文字符串,b是一个包含a的列表
直接在IDLE中输入a时,显示的是字符串a的数据格式,即GBK编码下的存储的实际数据
而print a时,这是解释器会把数据转换成一个容易理解的形式,中文显示出来
而在处理b这个包含中文字符串的列表时,print并没有这么智能地将GBK的编码转换成汉字。这是正常的情况,它只是程序的输出,并不会影响程序的运行(判断中文字符串是否相等,以及一些其他的字符串操作),所以不用担心
注:在python中,一切都是对象,对象中的__str__方法控制了对象在被print时的表现,具体可以自己查阅相关书籍



二、python 3.x的编码表现
python3.x对2做出了巨大的改动,其中一个就是IDLE的默认编码改为UTF8。
在python3.x下很多显示的问题消失了:


可以发现完全没问题

另外在处理文件时,python3.x的open函数支持在打开文件时指定编码(默认打开的编码是GBK ==!),如下:处理UTF8编码:


处理GBK编码:



另外值得注意的是,在3.x中,py文件的编码只能保存成utf8编码,GBK是非法的!

三、爬虫中的编码问题
最近很多鱼油在玩高端的爬虫,其中可能涉及到很多乱码问题。下面稍微提下如何判断爬下来的网页编码,以2.x为例:


如图,服务器在response的headers里面会指出返回内容的类型以及编码。如果编码不是你想要的,那么恭喜你,需要作一些编解码的转换来满足你的应用需求。另外你可能碰到gzip的压缩编码,那么需要用gzip的相关函数来解压缩。
大多数服务器都能根据用户在请求头构造的请求编码来返回相应编码的内容,这样就需要你自己来构造请求头,下面如下:




**** Hidden Message *****






glances 发表于 2014-11-25 22:15:23

+2

584250550 发表于 2014-11-25 22:19:29

给力,好好瞧瞧

〃忝書γě渎ぐ 发表于 2014-11-25 22:25:03

谢谢分享

流氓大叔 发表于 2014-11-26 08:34:12

最近一直是这个问题。来看看。

wei_Y 发表于 2014-11-26 09:58:07

爬虫出现403,加上User-Agent没用咋办。。

bevin 发表于 2014-11-26 10:27:18

wei_Y 发表于 2014-11-26 09:58
爬虫出现403,加上User-Agent没用咋办。。

服务器拒绝请求,有可能是参数错误

wei_Y 发表于 2014-11-26 10:36:01

bevin 发表于 2014-11-26 10:27
服务器拒绝请求,有可能是参数错误

我截得火狐的包。。写在字典里了。

bevin 发表于 2014-11-26 10:54:56

wei_Y 发表于 2014-11-26 10:36
我截得火狐的包。。写在字典里了。

哪个网站的?

892459897 发表于 2014-11-26 11:06:18

谢谢分享

wei_Y 发表于 2014-11-26 11:16:57

bevin 发表于 2014-11-26 10:54
哪个网站的?

百度。。

bevin 发表于 2014-11-26 11:41:36

wei_Y 发表于 2014-11-26 11:16
百度。。

没试过,你可以启用缓存试试

gl542400 发表于 2014-11-26 13:03:21

编码不是你想要的,那么恭喜你

戴宇轩 发表于 2014-11-26 17:36:00

学习了

elier0214 发表于 2014-11-26 21:45:16

刚学,还不怎么懂{:1_1:}

snailp 发表于 2014-11-26 23:07:29

顶顶

meijiasi12 发表于 2014-11-28 13:02:50

谢谢分享

wszjay 发表于 2014-11-28 17:07:02

看不到图?

落叶飞空 发表于 2014-11-28 17:42:58

学习一下,顶顶顶。

无名流浪者 发表于 2014-11-28 18:30:31

看看
页: [1] 2 3 4 5 6 7 8 9 10
查看完整版本: python编码问题初探