使用Python语言做网络爬虫或者写自动化脚本时,总会遇到“中文乱码”的问题,很是头疼。很多“中文乱码”的问题是跟Python的解码/编码有关,所以今天和大家说说Python的解码/编码(以Python2.7为例)。
1.什么是Python解码/编码?
Python里面的解码和编码也就是unicode和str这两种形式的相互转化。解码就是str -> unicode,相反的,编码是unicode -> str。
总的来说就是:unicode是Python解释器的内码,所有代码文件在导入并执行时,Python解释器会先将字符串使用你指定的编码形式解码成unicode,然后再进行各种操作。不管是对字符串的操作,还是正则表达式,还是读写文件等等最好都通过unicode来进行。
Python解释器在导入Python代码文件并执行时,会先查看文件头有没有编码声明(例如# -*- coding: utf-8 -*-等)。如果发现声明,如# -*-coding: utf-8 -*-,会将文件中的字符串从utf-8先解释成unicode的形式;如果文件头没有编码声明,则会以默认的ASCII来解释成unicode的形式。
2.解码函数decode()和编码函数encode()
在Python中,解码函数是decode(),编码函数是encode()。
﹒decode()的作用是将其他编码的字符串转换成unicode 格式,例如:name.decode(“utf-8”),表示将utf-8编码的字符串name转换成unicode
﹒encode()的作用是将unicode编码转换成其他编码的字符串,例如:
name.encode(“GB2312”),表示将GB2312编码的字符串name转换成GB2312
当代码中同时有编码声明(例如# -*- coding: utf-8 -*-等)和编码函数encode(‘gbk’),Python在执行时会优先选择真实编码gbk。当存在encode(‘gbk’)时,即便在开头申明了#-*- coding: utf-8 -*-,没有指定解码方式,程序是会报错的。
解决方案:在中文“哈哈”前加上字符“u”,直接使字符是unicode类型,不用再将“哈哈”去解码操作。
注意:上图中的 '\xb9\xfe\xb9\xfe'是“哈哈”的gbk编码;'\xe5\x93\x88\xe5\x93\x88'是“哈哈”的utf-8编码。上图说明,当存在encode(‘gbk’)时,即便在开头申明了#-*- coding: utf-8 -*-,在执行时会优先选择encode()函数中的gbk编码方式。
需要注意的一点是,假设stra=‘哈哈’,如果我们调用stra.encode(),这里涉及到一个隐士的类型转化,会先将stra转化成unicode,才能进行编码,这也是不太容易理解的地方。而在中文前添加“u”字符,就使得stra转化成unicode这一步略去。
3.Python解码
解码是Python自动进行的,我们在程序开头没有编码声明(如:#-*-coding:utf-8-*-),也没有指明解码方式,Python就会使用sys.defaultencoding指明的方式来解码。很多情况下sys.defaultencoding是ASCII。
4.Python编码
Python默认采用ASCII编码,而ASCII编码不能用来编码中文字符。举个简单的例子:
如下图,运行脚本时会有提示。因为Python编码默认是ASCII编码,不支持中文。
解决方案1:在文件开头输入支持中文的编码方式:# -*- coding: gbk -*-。
解决方案2:Python2.x默认是不支持中文的,我们在程序的开头加上#-*-coding:utf-8-*-,并在中文前加上“u”字符,也可以解决这个问题。这里的“u”表示将后面跟的字符串以unicode格式存储,然后Python会根据程序第一行的utf-8编码识别代码中的中文“你好”,然后转换成unicode对象(重申一下:中文前加“u”,直接免去“将字符串解码成unicode”这一步的操作哦)。
补充一点:如果在中文前没有添加“u”,仅仅在程序的开头加上#-*-coding:utf-8-*-,屏幕上打印出的不是“你好”,如下图。这是由于Python编码与控制台编码的不一致造成的。Windows下控制台中的编码使用的是gbk,而在代码中使用的utf-8,Python按照utf-8编码打印到gbk编码的控制台下自然就会不一致而不能打印出正确的汉字。
总之,在Python2.x版本中使用中文,最好在程序开头添加一行声明文件编码的注释:#-*-coding:utf-8-*-,然后在中文前添加“u”字符。可以不使用解码、编码函数,就尽量别使用(真的会绕晕的,哈哈……)。
原创文章,仅代表非比君个人观点,说的不一定是对的,欢迎大家指正。
用微信添加 非比测试 公众号即可订阅。转载请保留作者、公共账号信息,内容必须与本文保持严格一致,不得修改/替换/增减本文包含的任何文字,不得擅自增加小标题、引语、摘要等。本公众号一切内容禁止摘编、衍生及演绎。
领取专属 10元无门槛券
私享最新 技术干货