1、系统默认的脚本文件编码html
Python 默认脚本文件都是 ANSCII 编码的,当文件 中有非 ANSCII 编码范围内的字符的时候就要使用"编码指示"来修正。 一个module的定义中,若是.py文件中包含中文字符(严格的说是含有非anscii字符),则须要在第一行或第二行指定编码声明:python
# -*- coding=utf-8 -*-或者 #coding=utf-8 其余的编码如:gbk、gb2312也能够; 不然会出现相似:SyntaxError: Non-ASCII character '/xe4' in file ChineseTest.py on line 1, but no encoding declared; see http://www.pytho for details这样的异常信息;n.org/peps/pep-0263.htmlshell
命令查看脚本默认的编码方式
>>> import sys
>>> sys.getdefaultencoding()
'ascii'
>>> 网络
2.2 python中的编码与解码函数
先说一下python中的字符串类型,在python中有两种字符串类型,分别是str和unicode,他们都是basestring的派生类;str类型是一个包含Characters represent (at least) 8-bit bytes的序列;unicode的每一个unit是一个unicode obj;因此:字体
len(u'中国')的值是2;len('ab')的值也是2;网站
在str的文档中有这样的一句话:The string data type is also used to represent arrays of bytes, e.g., to hold data read from a file. 也就是说在读取一个文件的内容,或者从网络上读取到内容时,保持的对象为str类型;若是想把一个str转换成特定编码类型,须要把str转为Unicode,而后从unicode转为特定的编码类型如:utf-八、gb2312等;google
2.2.1 print 语句解释编码问题编码
print 是打印默认的编码方式,至关于对任何对象encode编码转化成str对象。默认是gbk的编码就是对Unicode进行自动的gbk编码,再按照gbk编码输出。url
当print语句碰到一个unicode目标的时候,会用当前python shell环境的默认编码格式首先对unicode对象进行encode(此时unicode对象已经变成了一个str对象了),而后再以默认编码格式为基础,根据其包含的汉字和编码的对应规则,把这个str对象解释成中文并显示出来。可是当print语句碰到的直接是个str目标的时候,就无论其从unicode转到str时用的编码格式是什么,直接用默认编码格式的对应规则来解释成中文。因此,当unicode对象转换成str时的编码格式和print语句的默认编码格式不一致的时候就会出现乱码现象。好比在cmd的python shell里面:
>>>uni = u'你好' #存入一个unicode对象 >>>print uni 你好 #能够正常显示 至关于Unicode.encode(gbk) >>>uni.encode("gbk") '\xc4\xe3\xba\xc3' #显示的是个str对象了,若是type(uni.encode("gbk"))获得的就是str对象 >>>print uni.encode("gbk") 你好 #能够正常显示,由于在cmd下的pythonshell里默认个编码格式就是gbk,gbk解析 >>>uni.encode("utf-8") '\xe4\xbd\xa0\xe5\xa5\xbd' #能够看到,encode用的编码格式不一样,编成的字符串也是不一样的 >>>print uni.encode("utf-8") 浣犲ソ #乱码,由于用了gbk中汉字和字符串编码格式对应规则去解释了用utf-8编码成的字符串。解释的编码格式不对应。 #######さらに###### >>>print '\xc4\xe3' #本身写出来的这么个字符串(前面不加r)的话也会被print解释成中文,按照编码格式输出 你 >>>print uni.encode("utf-8").decode("gbk") 浣犲ソ ''' 乱码,并且和上面的乱码同样,这是由于,在uni被utf-8 encode以后,这个对象变成了str对象,是'\xe4\xbd\xa0\xe5\xa5\xbd' 这个。 后来,它又被按照gbk的规则解码,又变回了unicode,可是此时它在内存里的二进制数据已经和最初的uni不同了。 最初的uni,应该是'\xc4\xe3\xba\xc3'.decode("gbk"),而如今的这个东西,他decode以前的字符串已经变过了。 这么一个东西再拿去print,又把它编码成了gbk格式,至关于前面那步decode没有作,变回了'\xe4\xbd\xa0\xe5\xa5\xbd'。 再解释成汉字,固然就和最开始用uni编码成utf-8格式再解释成汉字的乱码同样了 '''
2.2.2 脚本print 打印的正确方式
上面已经证实了系统的默认编码方式是gbk,就是print 最后正确的编码方式应该是gbk
两种解决编码不匹配的状况:
一是明确的指示出 s 的编码方式
# -*- coding: utf-8 -*-
s = '中文'
s.decode('utf-8').encode('gb2312')
二是更改 sys.defaultencoding 为文件的编码方式
#! /usr/bin/env python
# -*- coding: utf-8 -*-
import sys
reload(sys) # Python2.5 初始化后会删除 sys.setdefaultencoding 这个方法,咱们须要从新载入
sys.setdefaultencoding('utf-8')
str = '中文'
str.encode('gb2312')
3、实践经验中爬取数据的得到
# -*- coding: utf-8 -*- ''' #加油两个字能够很好的比较编码正确和错误 #### 错误的处理方式, s = "中文" print s #这里print就不是输出gbk的编码,是按照头文件utf-8的格式输出 # 结果:中文 print s.decode('utf-8') #结果中文,s进行解码称为Unicode,print打印就和系统print打印同样自动将Unicode进行 #解码,不用encode编码也能输出,可是最好转化成为字符串输出。 上面实例就是错误使用编码,错误使用编码会出现个别字体的乱码。 ''' ''' 要点一、声明头文件# -*- coding: utf-8 -*- 说明全部的代码和中文是utf-8的编码方式 要点二、print输出函数输出到前台cmd中的默认系统编码方式是GBK, 要点三、尽可能将Unicode转化成为字符串str (gbk或者utf-8),再去处理。 #unicode 转化成为字符串 s = u'加油' print s #结果:加油。缘由:系统自动将Unicode升级gbk编码成为字符串,而后系统print 打印gbk print s.encode('utf-8') #结果:鍔犳补。错误缘由:Unicode 编码成为utf-8的字符串形式,可是print打印系统是gbk的,编码冲突。 print s.encode('gbk') #结果:加油。缘由:和print s等价,认为编码了gbk,系统打印 ss = "加油" print ss #结果:鍔犳补。缘由:ss为utf-8的字符串str,print 打印的对应编码字符串是gbk的,因此编码冲突。 print ss.decode('utf-8').encode('gbk') #结果:加油。缘由:ss首先从字符串编码utf-8解码成为unicode,而后进行编码gbk,等价使用print ss.decode('utf-8')。 ''' ''' 3.1python中关于中文转换url编码的问题 爬虫的时候咱们常常会碰到中文连接编码出现变换的问题, 例如'丽江'中文在url的地址编码倒是'%E4%B8%BD%E6%B1%9F', 所以需 要作一个转换。这里咱们就用到了模块urllib。 ''' import urllib data = '丽江' print data.decode('utf-8').encode('gbk') #对utf-8的中文编码 print urllib.quote(data) #那咱们想转回去呢? print urllib.unquote('%E4%B8%BD%E6%B1%9F').decode('utf-8').encode('gbk') ''' '丽江'在网页编码是gbk的转换码是'%C0%F6%BD%AD',utf-8中的转化码是'%E4%B8%BD%E6%B1%9F',实际上是编码问题。 百度的是gbk,其余的通常网站好比google就是utf8的。因此能够用下列语句实现。 ''' #江苏课题的编码转化 import sys,urllib s = '江苏' print urllib.quote(s.decode(sys.stdin.encoding).encode('gbk')) print urllib.quote(s.decode(sys.stdin.encoding).encode('utf8')) for place in ['南京','无锡','徐州','常州','苏州','盐城','南通','连云港','淮安','盐城','扬州']: print urllib.quote(place) #################### #结果: ''' >>> 丽江 %E4%B8%BD%E6%B1%9F 丽江 %E4%B8%BD%E6%B1%9F %E6%B6%93%E8%8A%A5%E7%9D%99 >>> ''' #############################333