python的编码问题整理
一、编码和解码
1、编码(encode):将人类可以识别的语言(英文、中文等)转化成机器语言(01串)的过程,用于存储。
2、解码(decode):将机器语言转化成人类可识别的语言的过程,用于显示。
编码类型
1、ASCII编码:最早使用的编码方式
2、GBK编码:为了兼容中文,非ASCII编码
3、unicode编码:为了兼容所有语言,从ASCII扩展而来
4、utf-8编码:为了节省空间,对unicode的优化
二、py2中的string编码
1、python2默认的是ASCII编码方式
2、unicode是真正意义上的字符串;str是字节串。
3、乱码处理
1)cmd中的乱码
- 现象:
新建hello.py文件,内容如下
1 #coding:utf-8 2 print '果果'
在cmd中运行python hello.py
- 解决方法:中文前增加“u”
1 #coding=utf-8 2 print u"果果"
运行结果
- 原因
我们在win下的终端即cmd.exe去执行,cmd.exe本身也一个软件;当我们python2 hello.py时,python2解释器(默认ASCII编码)去按声明的utf8编码文件,而文件又是utf8保存的,所以没问题;问题出在当我们print'苑昊'时,解释器这边正常执行,也不会报错,只是print的内容会传递给cmd.exe用来显示,而在py2里这个内容就是utf8编码的字节数据,可这个软件默认的编码解码方式是GBK,所以cmd.exe用GBK的解码方式去解码utf8自然会乱码。
2)open()中的乱码
- 现象:
创建hello文本,保存成utf8:
我爱中国
代码如下
1 #coding=utf-8 2 f=open('hello.txt') 3 print f.read()
运行结果
C:\Python27\python.exe E:/pyClass/temp/hello.py
鎴戠埍涓浗
- 解决:
open()中加入encoding='utf-8'关键字参数,但是open()方法没有此参数;使用codecs.open(),代码如下:
1 #coding=utf-8 2 import codecs 3 f=codecs.open('hello.txt',encoding='utf8') 4 print f.read()
运行结果
C:\Python27\python.exe E:/pyClass/temp/hello.py
我爱中国
- 原因:
win的操作系统安装时是默认的gbk编码,当执行open函数时,调用的是操作系统打开文件,操作系统用默认的gbk编码去解码utf8的文件,自然乱码。
4、对于Python代码中避免遇到编码问题,有一些小建议:
- 字符编码声明:在代码开头声明编码格式
- 使用codecs的open函数处理文本文件
- 尽可能使用unicode而不是str:在所有字符串的引号前加
u
三、py3的string编码
1、py3默认编码方式utf-8
2、str类型存unicode数据,bytse类型存bytes数据
3、乱码处理
1)cmd打印中文,不存在乱码问题
2)open()文件乱码问题,处理同py2
3)网页的编码
1 #coding=utf-8 2 import requests 3 4 res = requests.get("http://www.baidu.com") 5 data = res.content 6 print(data) 7 print(type(data))
运行结果
"C:\Program Files\Python36\python3.exe" E:/pyClass/temp/hello.py b'<!DOCTYPE html>\r\n<!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charset=utf-8><meta http-equiv=X-UA-Compatible content=IE=Edge><meta content=always name=referrer><link rel=stylesheet type=text/css href=http://s1.bdstatic.com/r/www/cache/bdorz/baidu.min.css><title>\xe7\x99\xbe\xe5\xba\xa6\xe4\xb8\x80\xe4\xb8\x8b\xef\xbc\x8c\xe4\xbd\xa0\xe5\xb0\xb1\xe7\x9f\xa5\xe9\x81\x93</title></head> <body link=#0000cc> <div id=wrapper> <div id=head> <div class=head_wrapper> <div class=s_form> <div class=s_form_wrapper> <div id=lg> <img hidefocus=true src=//www.baidu.com/img/bd_logo1.png width=270 height=129> </div> <form id=form name=f action=//www.baidu.com/s class=fm> <input type=hidden name=bdorz_come value=1> <input type=hidden name=ie value=utf-8> <input type=hidden name=f value=8> <input type=hidden name=rsv_bp value=1> <input type=hidden name=rsv_idx value=1> <input type=hidden name=tn value=baidu><span class="bg s_ipt_wr"><input id=kw name=wd class=s_ipt value maxlength=255 autocomplete=off autofocus></span><span class="bg s_btn_wr"><input type=submit id=su value=\xe7\x99\xbe\xe5\xba\xa6\xe4\xb8\x80\xe4\xb8\x8b class="bg s_btn"></span> </form> </div> </div> <div id=u1> <a href=http://news.baidu.com name=tj_trnews class=mnav>\xe6\x96\xb0\xe9\x97\xbb</a> <a href=http://www.hao123.com name=tj_trhao123 class=mnav>hao123</a> <a href=http://map.baidu.com name=tj_trmap class=mnav>\xe5\x9c\xb0\xe5\x9b\xbe</a> <a href=http://v.baidu.com name=tj_trvideo class=mnav>\xe8\xa7\x86\xe9\xa2\x91</a> <a href=http://tieba.baidu.com name=tj_trtieba class=mnav>\xe8\xb4\xb4\xe5\x90\xa7</a> <noscript> <a href=http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u=http%3A%2F%2Fwww.baidu.com%2f%3fbdorz_come%3d1 name=tj_login class=lb>\xe7\x99\xbb\xe5\xbd\x95</a> </noscript> <script>document.write(\'<a href="http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u=\'+ encodeURIComponent(window.location.href+ (window.location.search === "" ? "?" : "&")+ "bdorz_come=1")+ \'" name="tj_login" class="lb">\xe7\x99\xbb\xe5\xbd\x95</a>\');</script> <a href=//www.baidu.com/more/ name=tj_briicon class=bri style="display: block;">\xe6\x9b\xb4\xe5\xa4\x9a\xe4\xba\xa7\xe5\x93\x81</a> </div> </div> </div> <div id=ftCon> <div id=ftConw> <p id=lh> <a href=http://home.baidu.com>\xe5\x85\xb3\xe4\xba\x8e\xe7\x99\xbe\xe5\xba\xa6</a> <a href=http://ir.baidu.com>About Baidu</a> </p> <p id=cp>©2017 Baidu <a href=http://www.baidu.com/duty/>\xe4\xbd\xbf\xe7\x94\xa8\xe7\x99\xbe\xe5\xba\xa6\xe5\x89\x8d\xe5\xbf\x85\xe8\xaf\xbb</a> <a href=http://jianyi.baidu.com/ class=cp-feedback>\xe6\x84\x8f\xe8\xa7\x81\xe5\x8f\x8d\xe9\xa6\x88</a> \xe4\xba\xacICP\xe8\xaf\x81030173\xe5\x8f\xb7 <img src=//www.baidu.com/img/gs.gif> </p> </div> </div> </div> </body> </html>\r\n' <class 'bytes'>
要正常显示的话,需要要使用decode()方法
1 #coding=utf-8 2 import requests 3 4 res = requests.get("http://www.baidu.com") 5 data = res.content 6 print(data.decode('utf-8'))
4、requests返回gbk乱码问题
现象:使用requests模块,发送请求,返回解码时报错
UnicodeEncodeError: 'gbk' codec can't encode character '\xab' in position 18864: illegal multibyte sequence
解决:修改python的默认编码,增加如下代码
1 # coding=utf-8 2 import io 3 import sys 4 import requests 5 6 sys.stdout=io.TextIOWrapper(sys.stdout.buffer,encoding='gb18030')
原因:
win7的默认编码格式是:gbk
cmd——chcp——936
python3的默认编码格式:utf-8
>>> sys.getdefaultencoding()
'utf-8'