Encode

by kinsly编码一直是python中的大坑,反正我是一直没搞明白,今天在做爬虫的时候,觉得实在是有必要把这些东西整理一下。什么是编码简单的来说就是,为了是计算机能够表达不同的文字,人们制定了一些表达字母符号的方法,常见的编码有ASCII,utf-8,汉字常见的有GBK,big5, GB18030。也就是说字符必须编码后才能被计算机所处理,计算机使用的缺省编码方式也就是计算机的内码。具体细节参见UnicodeUnicode是国际组织设计的,包括了世界上所有语言文字的编码方案。那么Unicode只是一种编码方案,并没有规定如何传输,保存编码。所以这就是为什么我们有UTF-8,UTF-7,UTF-16,这几种都是按照unicode设计,不同的具体编码方案。为什么UTF-8是比较常见的呢,是因为UTF-8与ISO-8859-1完全兼容。世界上有两个设计unicode的组织,一个是软件制造商协会,另一个是ISO,所以UTF-8好在能够兼容两个协会的标准。UTF-8是以8位为单元对UCS进行编码。内码windows目前已经支持unicode,但是很多文档和程序都是采用特定编码系统。所以我们在使用某些软件的时候,必须将unicode转化为软件支持的编码。如word只支持gb2312,但是好像也能识别unicode。所以如果想输出csv然后用word打开,需要转化为GBK或者GB18030,或者BOMUTF-8。BOM的意思是 Byte order MarkPython 遇到的问题

UnicodeDecodeError: 'charmap' codec can't decode byte X in position Y: character maps to $<$undefine$>$

这个问题一般来说是在输出的时候,没有对输出的内容进行encode,也就是说计算机内部存储的是unicode,而你需要对其进行encode。data_df.to_csv('some2.csv',encoding='gb18030') 或者是当你读取unicode保存的文件的时候,如json,你也需要对其进行转码。with open('a.json',encoding="utf-8") as data_file: data = json.load(data_file)

UnicodeEncodeError: 'gbk' codec can't encode character 'ufeff' in position 10: illegal multibyte sequence

这种问题往往是你确定的这种编码方式不能识别数据中的某些编码,也不一定是都识别不了,这时可以换一种编码方式,如GB18030之类的

TypeError: a bytes-like object is required, not 'str'

这个好像是,在读写的时候,要把str转化成编码,也就是二进制之类的,需要进行decode

TypeError: Expected String or Unicode

在用pandas读取json会出现,也可能是没有encoding的问题

设置默认encoding方式

import sys

reload(sys)

sys.setdefaultencoding('utf-8')

在python2.7有这样的用法,但是由于有些包默认不一定是utf-8,所以最好还是不要这样写。核心三原则
  • 因为某些原因, python 打开流读取出的是str,所以用你知道的每一种编码把它解码成unicode
  • 大概是因为同样的原因,python 的输出也是str, 但是任何一个unicode 只有到要输出的时候才编码成str
  • 在此之间,放弃该死的str,忘了它,当你开始处理的时候,确保你的每一个字符串对象都是unicode
  • python编码的意义
    不过好像python3已经没有了这种问题

    你导入的好几个模块我都没用过....不过能看出来是跳进了python2的encoding大坑了-_-
    总之,研究了近百篇文章后我才意识到,破解encoding问题不用那么复杂.
    不用''.encode().decode(),也不用sys.setdefaultencode之类
    只要你在全文里除了最后输出部分,保证其余每一个字符串全都是unicode格式就行了.
    比如直接手写的字符串你好,就要写成u'你好'
    在比如,合并数组为字符串时, 就u''.join(arr)
    其余的就unicode(s)
    最后实在不行了才.decode().encode()
    至于codex模块和charset, ccharset等检测字符串编码的,遇到中文一样傻眼,劝别试.

    看到另一个回答,这样说,其实也挺有道理,就是不想太纠结,就不要搞太复杂。简单粗暴decode & encode通常我们需要decode()与encode()来进行解码与编码
    decode     encode

    str ---------> unicode ---------->str

    在python2中,编码之间的转换需要通过unicode,所以假如你想将由gbk编码的字符串转换为utf-8编码,需要先将其转换为unicode,再将其转换为utf-8编码的字符串u = u'中文' #显示指定unicode类型对象u str = u.encode('gb2312') #以gb2312编码对unicode对像进行编码 str1 = u.encode('gbk') #以gbk编码对unicode对像进行编码 str2 = u.encode('utf-8') #以utf-8编码对unicode对像进行编码 u1 = str.decode('gb2312')#以gb2312编码对字符串str进行解码,以获取unicode u2 = str.decode('utf-8')#如果以utf-8的编码对str进行解码得到的结果,将无法还原原来的unicode类型而在python3中,取消了unicode类型,代替它的是使用unicode字符的字符串类型(str),也就是说,上面的说明可以转化为下面这种形式
     decode           encode

    bytes ---------> str(unicode)------------>bytes

    u = '中文' #指定字符串类型对象u str = u.encode('gb2312') #以gb2312编码对u进行编码,获得bytes类型对象str u1 = str.decode('gb2312')#以gb2312编码对字符串str进行解码,获得字符串类型对象u1 u2 = str.decode('utf-8')#如果以utf-8的编码对str进行解码得到的结果,将无法还原原来的字符串内容具体可参见个人经验用pandas的函数,df.to_csv('a.csv', encoding='gbk') 可能会方便一点。或者df.to_csv('a.csv', encoding='gbk',mode = 'a') 这样可以接着写,类似于append的功能当然也可以直接csv包中的函数直接保存with open('m.csv','w',encoding = 'utf-8') as f: writer = csv.writer(f) for i in range(1,len(data_total)): writer.writerow(data_total) 但是这样存储出来的csv用word打开可能是乱码。这时候可以用记事本将其打开,另存为的时候将其编码格式修改为unicode,这样我的word就能识别这些数据致谢:谢谢汪老师在这个过程之中的帮助。reference:
  • python编码的意义 https://segmentfault.com/a/1190000004166137
  • https://segmentfault.com/q/1010000004620523
  • http://stackoverflow.com/questions/3218014/unicodeencodeerror-gbk-codec-cant-encode-character-illegal-multibyte-sequen
  • 相关内容推荐