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&amp;tpl=mn&amp;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>&copy;2017&nbsp;Baidu&nbsp;<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>&nbsp; <a href=http://jianyi.baidu.com/ class=cp-feedback>\xe6\x84\x8f\xe8\xa7\x81\xe5\x8f\x8d\xe9\xa6\x88</a>&nbsp;\xe4\xba\xacICP\xe8\xaf\x81030173\xe5\x8f\xb7&nbsp; <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'

posted @ 2018-07-30 16:48  小白2510  阅读(512)  评论(0编辑  收藏  举报