编码探讨: 该以什么编码打开"gb2312"文本?

来源:互联网 发布:开淘宝店怎么刷销量 编辑:程序博客网 时间:2024/06/05 10:48

在Python中,对文本文件进行操作时,一不小心就会遇到编码问题

出错示例:

1.UnicodeEncodeError: ‘gbk’ codec can’t encode character.
2.UnicodeEncodeError: ‘gb2312’ codec can’t encode character.
3.UnicodeEncodeError: ‘UTF-8’ codec can’t encode character


为了避免再遇到此类问题,现在来探究下gb2312,gbk与gb18030间的关系


基础知识:
1. 编码集关系: gb2312gbkgb18030
2. gb2312字符:  哈哈哈我去你大爷的
3. gbk字符:   妳爺愛情國家
4. gb18030字符: āōáóǎēǒǎɑ


结论一

Windows中,以gb2312 gbk gb18030编码存储的文件,会被映射到gb2312
就是说, 以gbk/gb2312保存的文本,程序读取该文本时, 仍会认为编码是gb2312


验证:
  编写程序, 依次创建gb2312 gbk gb18030 utf-8编码的文本, 然后尝试依次写入gb2312字符 gbk字符 gb18030字符, 最后依次检测其编码

import chardet# 创建各种编码文本for encoding in ['gb2312', 'gbk', 'gb18030', 'utf-8']:    txtName = '测试'+encoding+'.txt'    with open(txtName, 'w', encoding=encoding) as text:        try:            text.write('哈哈哈我去你大爷的')        except:            print(encoding+'无法写入 哈哈哈我去你大爷的')        try:            text.write('妳爺愛情國家')        except:            print(encoding+'无法写入 妳爺愛情國家')        try:            text.write('āōáóǎēǒǎɑ')        except:            print(encoding+'无法写入 āōáóǎēǒǎɑ')print()# 检测其编码for encoding in ['gb2312', 'gbk', 'gb18030', 'utf-8']:    txtName = '测试'+encoding+'.txt'    with open(txtName, 'rb') as test:        content = test.read()        encoding = chardet.detect(content)    print(txtName+'检测结果: ')    print('编码: {},可信度: {}\n'.format(encoding['encoding'], encoding['confidence']))

结果:
  这里写图片描述
  
查看文本:
  这里写图片描述

gb2312仅能保存gb2312的文字
chardet检测结果: gb2312
notepad++显示结果: ANSI(GBK)


gbk 可以保存gb2312gbk的文字
chardet检测结果: gb2312
notepad++显示结果: gb2312


gb18030可以保存gb2312,gbkgb18030的文字
chardet检测结果: gb2312
notepad++显示结果: gb2312


utf-8 可以保存所有编码的文字
chardet检测结果: utf-8
notepad++显示结果: utf-8


总结

gbkgb18030都被映射到了gb2312

结论二

在程序中应以文本中字符最大的编码集打开该文本,否则会造成乱码/打开失败.


验证:
 编写程序, 依次创建gb2312gbk gb18030 utf-8编码的文本, 然后尝试依次写入gb2312字符 gbk字符 gb18030字符, 最后依次检测其编码

import chardet# 遍历四个测试文本for c in ['gb2312', 'gbk', 'gb18030', 'utf-8']:    textName = '测试'+c+'.txt'    print('\n测试文本: '+textName)    with open(textName, 'rb') as test:        content = test.read()    encoding = chardet.detect(content)    print('\t猜测: 编码-{},可信度-{}'.format(encoding['encoding'], encoding['confidence']))    # 依次以4种编码去打开文本    for encoding in ['gb2312', 'gbk', 'gb18030', 'utf-8']:        with open(textName, 'r', encoding=encoding) as test:            try:                content = test.read()                print('\t成功: {}'.format(encoding))                print('\t内容: '+content)            except:                print('\t失败: {}'.format(encoding))                print('\t内容: ')

结果:
这里写图片描述

总结:

  1. 仅含有gb2312,可用gb2312, gbkgb18030打开
  2. 含有gb2312gbk,可用gbkgb18030打开
  3. 含有gb2312, gbkgb18030,仅能用gb18030打开
  4. gb编码文本不能用utf-8打开, utf-8编码文本不能用gb编码文本打开
原创粉丝点击