对于人类能够识别的字符,计算机会根据某一对应关系将其转换为二进制形式进行保存。这个对应关系就是字符编码表,即什么样的字符对应什么样的二进制编码。这种字符编码表往往是多种多样的,因此,如果我们想要将一个未知编码的二进制文件转换为可读文本进行显示,就需要考其使用的是什么类型的字符编码。关于字符编码的进一步介绍见文章字符集和字符编码

现实中,往往根据各种字符编码的特征字符来猜测当前文件使用的是什么类型的字符编码。但是许多字符对于不同字符编码是通用的,区别在于每种编码可能使用不同的字节序列来存储同一字符,根据这一特性再进一步处理。在Python中,chardet库能够提供了实现字符编码自动检测的函数。chardet支持绝大部分常见字符编码的识别,其官方仓库见:chardet。chardet安装指令如下:

pip install chardet

1 使用

基础使用

chardet提供detect函数接口实现字符编码的自动检测。detect函数接受一个参数,即非Unicode字符串。它返回一个字典,其中包含自动检测到的字符编码和范围为0到1的置信度,还有语言类型。

# 导入库
import urllib.request
import chardet
# 读取网站
rawdata = urllib.request.urlopen('http://baidu.com/').read()
# 可以看到使用的是ascii编码
chardet.detect(rawdata)
{'encoding': 'ascii', 'confidence': 1.0, 'language': ''}
# 读取网站
rawdata = urllib.request.urlopen('http://en.people.cn/').read()
# 可以看到使用的是utf-8编码
chardet.detect(rawdata)
{'encoding': 'utf-8', 'confidence': 0.99, 'language': ''}
# 创建utf-8字节类型数据
data = bytes('hello, world', encoding='utf-8')
print(data)
chardet.detect(data)
b'hello, world'

{'encoding': 'ascii', 'confidence': 1.0, 'language': ''}
# bytes类型可以直接通过python的decode函数进行解码
data.decode('ascii')
'hello, world'
# 创建utf-8字节类型数据,这里可以看到utf-8是最高效的编码方式。
data = bytes('hello, world!你好世界!', encoding='utf-8')
print(data)
chardet.detect(data)
b'hello, world!\xe4\xbd\xa0\xe5\xa5\xbd\xe4\xb8\x96\xe7\x95\x8c\xef\xbc\x81'

{'encoding': 'utf-8', 'confidence': 0.9690625, 'language': ''}
# bytes类型可以直接通过python的decode函数进行解码
data.decode('utf-8')
'hello, world!你好世界!'
data = bytes('你好世界', encoding='GBK')
# 识别可能错误
chardet.detect(data)
{'encoding': None, 'confidence': 0.0, 'language': None}
# 需要更丰富的字符数据提高识别率
data = bytes('你好世界,你好', encoding='GBK')
chardet.detect(data)
{'encoding': 'GB2312', 'confidence': 0.99, 'language': 'Chinese'}

大量文本识别

如果您正在处理大量文本,您可以调用UniversalDetector,以加快识别速度。下面的代码首先创建一个UniversalDetector对象,然后对大型文本分块识别,每个文本块用其检测方法feed。如果检测器达到最小置信阈值,它将设置detector.done为True,进而输出当前文本的字符编码。

import urllib.request
from chardet.universaldetector import UniversalDetector usock = urllib.request.urlopen('http://baidu.com/')
detector = UniversalDetector()
for line in usock.readlines():
detector.feed(line)
if detector.done: break
detector.close()
usock.close()
print(detector.result)
{'encoding': 'ascii', 'confidence': 1.0, 'language': ''}

对于多个文件或多个字符串,也可以使用UniversalDetector加快识别速度。


from chardet.universaldetector import UniversalDetector texta = bytes('hello, world', encoding='utf-8')
textb = bytes('你好世界,你好', encoding='GBK') detector = UniversalDetector()
for data in [texta,textb]:
# 检测器重置
detector.reset()
detector.feed(data)
if detector.done: break
detector.close()
print(detector.result)
{'encoding': 'ascii', 'confidence': 1.0, 'language': ''}
{'encoding': 'GB2312', 'confidence': 0.99, 'language': 'Chinese'}

UnicodeDammit的使用

UnicodeDammit是beautifulsoup的内置库, 用于猜测字符编码。在UnicodeDammit中集成了chardet模块使得我们可以快速获取字符编码。

from bs4 import UnicodeDammit

data = bytes('你好世界,你好', encoding='GBK')
dammit = UnicodeDammit(data)
# 解码结果
print(dammit.unicode_markup)
# 打印编码结果
print(dammit.original_encoding)
# 或直接调用chardet
print(dammit.detector.chardet_encoding)
你好世界,你好
gb2312
GB2312

2 参考

最新文章

  1. 扩展Unity的方法
  2. maven仓库没有的包依赖
  3. postgresql - 服务配置
  4. 使用JS构建简单Map(转)
  5. 一个简单的C#加密解密类
  6. padding与margin的差别
  7. JavaScript Web Application summary
  8. 王立平--PopupWindow
  9. ThinkPHP5.0学习1 — 命名空间
  10. 《深入理解Java虚拟机》学习笔记之工具
  11. 剑指Offer——中国银行面试知识储备
  12. Codechef August Challenge 2018 : Safe Partition
  13. canvas画圆角矩形的方法
  14. python3 操作配置文件
  15. Linux Apache虚拟主机配置方法
  16. 水晶报表使用IEnumerable<T>数据源
  17. oracle显示一个月的所有天数
  18. How to fix TFS workspace mapping error in Jenkins
  19. Linux系统命令缩写
  20. 【原创】QString 函数 replace()indexOf()、 lastindexOf()

热门文章

  1. 设计模式之观察者模式_C++
  2. react 可视化编辑器1
  3. PHP + ELK实现日志记录
  4. 42.JSON Web Token认证
  5. DQL语句
  6. dns隧道攻击原理及常用工具流量分析
  7. 部署redis-cluster
  8. CSP-S游记
  9. 图学习【参考资料2】-知识补充与node2vec代码注解
  10. (译)TDD(测试驱动开发)的5个步骤