1. chardet是什么

chardet是python中比较常用的一个编码方式检测库,需要注意的是它只检测并返回检测结果,并不负责对原数据做什么处理。

可以使用PIP命令安装:

pip install chardet

2. 如何使用

2.1 API简介

一般都是调用chardet.detect传入一个字节数组,返回一个字典,此字典中存放分析的结果,一个可能的分析结果字典:

{
'encoding': 'ISO-8859-1',
'confidence': 0.44923076923076927,
'language': ''
}

encoding: 可能的编码方式

condidence: 识别的正确率是多少,这是一个区间[0, 1]上的值,值越大表示结果越可信

language: 字节码中存放的可能会是什么语言

2.2 读取配置文件时自动识别编码方式

只要是一个灵活的软件都会提供配置文件来让用户根据自己需要进行定制,但是我们没法保证用户究竟是使用什么鬼东西来编辑这个配置文件的,vim?notepad?editplus?奇奇怪怪的文本编辑工具一大堆,如果强制配置文件只能使用UTF-8格式的甚至还可能会碰上notepad的bom,要了命了,所以一个比较好的方式是在读取配置文件的时候能够自动检测它的编码方式,这样就无需关心用户究竟是使用什么鬼东西编辑的。一个可能的例子如下:

#! /usr/bin/python

import chardet
import json class EncodingUtil:
"""
编码工具类
"""
@staticmethod
def decode(content):
"""
读取字节数组为字符串
:param content: a byte array
:return:
"""
encoding = chardet.detect(content)['encoding']
return content.decode(encoding) class ConfigurationLoader:
"""
配置文件加载类
"""
@staticmethod
def load_config(config_path):
with open(config_path, 'rb') as config_file:
config_content = EncodingUtil.decode(config_file.read())
return json.loads(config_content) if __name__ == '__main__':
print(ConfigurationLoader.load_config('D:/config.json'))

2.3 爬虫中用来判别网页的编码方式

呃,貌似现在python已经成为爬虫的代名词,正常的套路网站内容都是按照UTF-8编码返回的,但是总有一些非主流站,会以奇奇怪怪的编码返回(根据笔者的经验,国内的网站一般也就是UTF-8和GB2312的,GB2312估计是因为很多编写网页的开发工具默认是GB2312的,写网页的家伙没改然后就这样子了呗),如果是有针对性的爬虫(时髦的说法叫做垂直领域爬虫),大不了我们失败几次之后专门做下编码格式转换就可以了,毕竟写爬虫基本就是不断处理异常情况,但是如果写的是通用爬虫,我们甚至都不知道爬虫会去哪里抓取内容更别提内容的编码方式了,所以在这种情况下在处理内容之前要进行一个编码转换,将其转换为宇宙通用的UTF-8格式,一个简单的例子如下:

#! /usr/bin/python

import chardet
import urllib3 class Spider:
"""
蜘蛛侠,爬爬爬
"""
pool_manager = urllib3.PoolManager() @staticmethod
def get(url):
return Spider.pool_manager.urlopen('GET', url) class EncodingUtil:
"""
编码工具类
"""
@staticmethod
def decode(content):
"""
读取字节数组为字符串
:param content: a byte array
:return:
"""
encoding = chardet.detect(content)['encoding']
return content.decode(encoding) if __name__ == '__main__':
# UTF8格式编码的
response = Spider.get('http://www.baidu.com/')
html = EncodingUtil.decode(response.data)
print(html) # GB2312格式编码的,找了好久才找到一个GB2312编码的...
response = Spider.get('http://www.hzsjwjcj.gov.cn/')
html = EncodingUtil.decode(response.data)
print(html)

当正确读取到内容之后就可以传给bs处理啦,chardet在爬虫中的应用大致就是这样子。

2.4 检测大文件

检测编码方式是需要一定的数据量作为参考的,当要检测一个特别大的文件的时候,比如一个几个G大的文件,没必要全部输入太浪费了,但是究竟给它多少数据做检测比较合适呢,1M?10M?100M?这个还真不知道....

所以这个时候我们就可能需要它提供一种方式,我们一点一点的把数据喂给它,当能够确定编码方式的时候就立即返回。哈,它确实提供了这么一种方式:

#! /usr/bin/python

import chardet
from chardet.universaldetector import UniversalDetector class EncodeUtil:
"""
编码工具类
"""
@staticmethod
def detect_big_file(file_path, block_size=1000):
"""
用于检测大文件的编码方式
:param file_path: str,要检测文件的路径
:param block_size: 每次读取的块大小
:return:
"""
detector = UniversalDetector()
with open(file_path, 'rb') as big_file:
block = big_file.read(block_size)
while block and not detector.done:
detector.feed(block)
block = big_file.read(block_size)
detector.close()
return detector.result if __name__ == '__main__':
print(EncodeUtil.detect_big_file('D:/foo.txt', 1024))

网上流传的版本都是每次读取一行,但是这种方式对于整个大文件只有一行或者是每一行都巨长的情况下直接就歇菜了,所以一个比较好的方式是将每次能够读取的长度把握一下。

通过上面的实验我们也可以总结出来,检测的数据量越少结果就越可能产生偏差,输入的数据量越大结果就可能越正确,所以也明确了chardet的应用场景,当只有几个字节的时候就别指望chardet能给出多正确的结果了。

3. 需要注意的一些坑

如果看到检测的返回值是这个样子的:

{
'encoding': 'ascii',
'confidence': 1.0,
'language': ''
}

不要急着感叹于chardet的牛叉竟然可以100%的确定是ASCII编码,这个八成就是没有检测出来,因为chardet.detect方法的默认返回值就是这个,贴源代码有图有真相:

# Default to ASCII if it is all we've seen so far
elif self._input_state == InputState.PURE_ASCII:
self.result = {'encoding': 'ascii',
'confidence': 1.0,
'language': ''}

参考资料:

1. https://pypi.python.org/pypi/chardet/

2. https://github.com/chardet/chardet

使用chardet判断编码方式的更多相关文章

  1. 【python】python编码方式,chardet编码识别库

    环境: python3.6 需求: 针对于打开一个文件,可以读取到文本的编码方式,根据默认的文件编码方式来获取文件,就不会出现乱码. 针对这种需求,python中有这个方式可以很好的解决: 解决策略: ...

  2. 【java】乱码处理+编码转化+判断字符串编码方式

    之前有一篇是修改IDE的编码,服务器的编码等处理乱码,但是在所有环境因素上,保证了编码方式之后,也会有前台传递给后台[get方式提交]传递给后台的编码方式是非UTF-8的,也会有例如FTP服务器的编码 ...

  3. 用chardet判断字符编码的方法

    转自http://www.cnblogs.com/xiaowuyi/archive/2012/03/09/2387173.html 用chardet判断字符编码的方法   1.chardet下载与安装 ...

  4. python chardet模块查看字符编码方式

    电脑配置:联想笔记本电脑 windows8系统 Python版本:2.7.8 本文章撰写时间:2014.12.25 作者:陈东陈 阅读说明: 1.本文都是先解释,后放图片: 2.文中斜体部分要么为需要 ...

  5. VBA 判断一个TXT编码方式,再创建一个新的文件,复制数据进去

    如题,先读取一个文本文件判断编码(Unicode  ANSI),就这两种编码然后将txt导入到excel表中,最后处理完成,再创建一个相同编码,不同文件名的txt文件,把新数据放进去 Sub test ...

  6. python批量修改文件内容及文件编码方式的处理

    最近公司在做tfs迁移,后面要用新的ip地址去访问tfs 拉取代码  ,所以原来发布脚本中.bat类型的脚本中的的ip地址需要更换 简单说下我们发布脚本层级目录 :每个服务站点下都会有一个发布脚本 . ...

  7. java爬虫爬取网页内容前,对网页内容的编码格式进行判断的方式

    近日在做爬虫功能,爬取网页内容,然后对内容进行语义分析,最后对网页打标签,从而判断访问该网页的用户的属性. 在爬取内容时,遇到乱码问题.故需对网页内容编码格式做判断,方式大体分为三种:一.从heade ...

  8. [No000040]取得一个文本文件的编码方式

    using System; using System.IO; using System.Text; /// <summary> /// 用于取得一个文本文件的编码方式(Encoding). ...

  9. Java实现将任何编码方式的txt文件以UTF-8编码方式转存

    本文利用JDK中的BufferedReader和BufferedWriter实现将任何编码方式的txt文件以UTF-8编码方式转存. UTF-8(8-bit Unicode Transformatio ...

随机推荐

  1. 【第一周】第一周工作统计(psp)

    项目:词频统计 项目类型:个人项目 项目完成情况:已完成 项目改进:未变更 项目日期:2016.9.3-2016.9.4 3号 类别c 内容c 开始时间s 结束e 中断I 净时间T 项目实践 构思   ...

  2. javac和java的使用

    java -Xmx128m -Dfile.encoding=gbk -cp ./;bin/;./*;lib/* com.qianlima.crawlOthers.Icp REM REM block e ...

  3. rem和em学习笔记及CSS预处理

    1.当元素A的字体单位是n rem时,它将根据根元素(html)的font-size的大小作为基准,比如   parent-div中的em-div的font-size为2rem,他的基准就是html的 ...

  4. Mac下Java JNI 调C

    简介 JNI的实现步骤如下: 编写带有native声明的方法的Java类 使用javac命令编译编写的Java类 使用java -jni className 来生成后缀名为.h的头文件 使用其他语言( ...

  5. Java容器深入浅出之List、ListIterator和ArrayList

    List是Collection接口的子接口,表示的是一种有序的.可重复元素的集合. List接口的主要实现类ArrayList和Vector,底层都是维护了一套动态的,可扩展长度的Object[]数组 ...

  6. 第195天:js---函数对象详解(call、apply)

    一.call 1.call供爷法则 // 对象1 var myclass={ getAllStudentsNumbers:function(num1,num2){ return num1+num2; ...

  7. SQL Server中使用自定义指定顺序排序

    比如需要对SQL表中的字段NAME进行如下的排序:张三(Z)李四(L)王五(W)赵六(Z) 如果想按 “ 张三.李四.王五.赵六”的顺序排序,则可以使用以下语句: order by charindex ...

  8. 关于qt中的tr()函数

    关于qt中的tr()函数 在论坛中漂,经常遇到有人遇到tr相关的问题.用tr的有两类人: (1)因为发现中文老出问题,然后搜索,发现很多人用tr,于是他也开始用tr (2)另一类人,确实是出于国际化的 ...

  9. [NOI2016]优秀的拆分 后缀数组

    题面:洛谷 题解: 因为对于原串的每个长度不一定等于len的拆分而言,如果合法,它将只会被对应的子串统计贡献. 所以子串这个限制相当于是没有的. 所以我们只需要对于每个位置i求出f[i]表示以i为开头 ...

  10. Unity3D for VR 学习(8): Unity Shader概述

    从西安到北京高铁上,一位VR老外团队的华人leader对VR技术做了画龙点睛: “3D游戏的核心部分在Render, 国内很多团队美术.程序中间缺失严重.所以3d游戏做不好. VR这块更是至关重要.” ...