先简单介绍一下编码的状况,咱们都知道机器上显示的字符最终存在计算机内存里都是以二进制码的形式存在的。html
最开始的计算机字符只能用ASCII编码的方式去存储,而一个ASCII码占用一个字节,也就是说ASCII编码最多只能编码256个字符(键盘上全部的半角字符)。 但为了表示别的国家文字,就必须对原有的字符编码方式进行扩充。而对于中文来讲,主要有两种编码方式,分别是gb2312和gbk,前者主要是用于编码简体中文字符,然后者除了简体中文字符还包括繁体中文字符。计算机迅速国际化以后,编码便不能只局限于英文字符和中文字符,因而出现了一个叫Unicode编码的方式,这种编码方式对每一个字符都使用四个字节的方式存储,这样一来就足够表示全部字符了,但事实上全部的半角字符咱们只须要1个字节来表示便足够了,所有字符都用Unicode编码方式的话,很容易形成资源浪费的状况,因此做为折中的考虑,UTF-8逐渐成为全球的流行的编码标准,UTF-8编码可以根据字符分别不一样的字节大小,英文字符依然用一个字节表示,而中文有些则是两个字节表示,有些则是三个字节。node
简单介绍事后,如下内容所有用中文的编码和python3.x环境(写python代码的时候)做为例子。python
顾名思义,编码就是把一个字符编码成二进制码存起来的方式,而解码就是把这个二进制码按照本来编码的规则还原成原来的字符。windows
当咱们打开记事本,而后打下一行字符的时候,对机器来讲都是一串不可识别的字符,因而咱们保存的时候,就是要对这些咱们输入的字符进行编码了。若是你输入一串非英文字符,计算机会提醒你有些字符不能正确编码(windows中文版的话没有这种状况,由于你按下ctrl+s计算机会有一个默认的中文编码方式,则没有出现没法编码的状况。此处指的是英文版操做系统,固然中文操做系统也能够自主选择编码方式的,请往下看~),以下图:python3.x
这个提示是说,若是你把这个文本保存为ANSI编码的文本文件时,有些Unicode字符会丢失,问你是否肯定,咱们先点ok保存,看看文本效果:浏览器
当咱们去打开的时候,和编码相对的概念,解码就要用到了,系统会检测到这个文本是一个ANSI文本,因而用ASCII编码方式去解码,结果没法正常解析,出现乱码,情理之中。(这是英文系统会出现的步骤,中文系统的测试由此处开始)。学习
咱们删除这个文件,从新创建一个,而后输入一样的内容,此时不要直接保存,点击 【文件】-->【另存为】,下面有选择编码的下拉列表,个人机器记事本只能使用四种编码方式(以下所示)测试
咱们选择UTF-8,保存,没有出现任何提示,打开文本,内容正常显示(以下图所示)。网站
而后咱们注意到写网站的时候咱们会写<meta charset='utf-8'>,这里指定的utf-8是指定编码方式仍是解码方式呢,其实都不是,由上面所述,编码方式取决于咱们写完文本以后保存所选择的编码方式。而浏览器解码呢,取决于浏览器的设置(这个表述并不许确,请往下看,就会明朗),这个设置固然也是能够本身修改的,在这里:编码
咦,怎么还有这个东西~
回到前面meta里面指定的编码有什么用呢,这里的编码是你手工告诉浏览器说你这个网页是使用什么编码去保存的,而后用浏览器去打开的时候,浏览器会用自己设置的编码方式去解码内容,当遇到<meta charset='utf-8'>的时候,浏览器会放弃设置中的方式,改用你指定的charset去解码内容,以保证内容都能正常显示,下面咱们来测试一下:
新建一个Test.html,用notepad++(为了方便)打开,选择编码方式为gb2312(nodepad++设置:【编码】-->【编码字符集】-->【中文】->【GB2312】),而后写下代码(以下图所示),在这里咱们“骗”浏览器说咱们用utf-8编码(但事实上咱们是用GB2312啊):
而后用ie打开看看效果:
浏览器“被骗“以后,果真不能正确解码内容了,而后咱们此时强制把浏览器的编码方式设置为GB2312,不能刷新(为何?),结果以下:
咱们无论浏览器了,编辑Test.html,保存编码方式为UTF-8,而后刷新(此时浏览器编码方式仍是GB2312),浏览器解析到<meta charset='utf-8'>的时候,则使用utf-8编码方式,结果就能正常显示.了...
在学习过程当中,不少人会抛出一串乱码求解决方案,而不少人的建议就是使用UTF-8,反正不知道为何,编码错了,就用UTF-8试试,当改为UTF-8以后(python中就是在文件第一行加上#encoding:utf-8或者对字节码使用.decode('utf-8')之类),还不能成功的话,接下来就不知道怎么作了。 这种作法都只是碰运气尝试,并无针对性修改,当理解了这种状况以后,面对编码问题并不难解决。
既然问题是从python学习过程当中跑出来的,那就用python再写一个例子好了,用open去写文件的时候能够传入一个encoding参数用于指定编码方式,一样的,读文件的时候encoding参数就视做解码方式。咱们编写如下python代码:
path = r'C:\Test\test.txt' with open(path, 'w', encoding='gb2312') as f: f.write("测试编码") with open(path, 'r', encoding='utf-8') as f: print(f.read())
运行查看结果,很明显吧,解码错误~
咱们用UTF-8去解码文本,结果报错说这不是UTF-8编码。
把代码 with open(path, 'r', encoding='utf-8') as f: 修改成 with open(path, 'r', encoding='gb2312') as f: ,从新运行py文件运行,结果以下
若是一开始咱们不加encoding这个参数,打印的内容也能正常显示,由上述可知,当咱们打开一个文件的时候,系统检测到这个文件的编码方式,而后去解码文件内容的,但咱们在用python读文件的时候并无去“打开文件“这个步骤啊, 这就须要用到上述提到的#encoding:utf-8的做用了,这句注释指定了咱们当前py文件的默认编码方式,咱们编写py文件的时候,都有一个默认的编码方式,而后这份代码的编码和解码(若是没有特别指定的话),都会按照这个方式来进行,这就解释了咱们读的时候是应该是字节码,打印出来倒是字符的缘由了,是python解释器用默认编码方式解码,帮咱们作了这个步骤。
一样的道理,咱们去爬一个网页内容的时候也是,爬到的是字节码,而后咱们要调用decode()方法对字节码进行解码,因此如今就知道若是出现乱码,缘由应该从哪里找起了吧,并非都是简单一句“试试UTF-8”就能解决全部状况的。
至此,以上为本人对字符编码与解码的一些拙见,若有不妥之处,敬请提出斧正。
尊重知识产权,转载引用请通知做者并注明出处!