python模块chardet库下载及安装使用介绍

python 模块 chardet下载及介绍

在处理字符串时,常常会遇到不知道字符串是何种编码,如果不知道字符串的编码就不能将字符串转换成需要的编码。面对多种不同编码的输入方式,是否会有一种有效的编码方式?chardet是一个非常优秀的编码识别模块。
chardet 是python的第三方库,需要下载和安装。下载的地址有:
1.推荐地址: http://download.csdn.net/download/aqwd2008/4256178
2.官方地址: http://pypi.python.org/pypi/chardet
如果采用源代码安装方法,有可能会提示缺少setuptools这个模块。因此这里我们采用另外一种更为方便的安装方法,不论你选择哪种安装包,将它解压得到其中的文件夹【chardet】将这个文件夹复制到【python安装根目录\Lib\site-packages】下,确保这个位置可以被python引用到。如果不能被引用到请加入环境变量。
在安装完chardet模块,我就可以使用它了,来看一段示例代码。
1 import chardet  
2 import urllib  
3   
4 #可根据需要,选择不同的数据  
5 TestData = urllib.urlopen('http://www.baidu.com/').read()  
6 print chardet.detect(TestData)  
7   
8 运行结果:  
9 {'confidence': 0.99, 'encoding': 'GB2312'}
运行结果表示有99%的概率认为这段代码是GB2312编码方式。
另外一个相对高级的应用。
[python] view plaincopy

复制代码
 1 import urllib  
 2 from chardet.universaldetector import UniversalDetector  
 3 usock = urllib.urlopen('http://www.baidu.com/')  
 4 #创建一个检测对象  
 5 detector = UniversalDetector()  
 6 for line in usock.readlines():  
 7     #分块进行测试,直到达到阈值  
 8     detector.feed(line)  
 9     if detector.done: break  
10 #关闭检测对象  
11 detector.close()  
12 usock.close()  
13 #输出检测结果  
14 print detector.result  
15   
16 运行结果:  
17 {'confidence': 0.99, 'encoding': 'GB2312'}

 

应用背景,如果要对一个大文件进行编码识别,使用这种高级的方法,可以只读一部,去判别编码方式从而提高检测速



Python中的chardet库使用方法

简单用法

chardet的使用非常简单,主模块里面只有一个函数detect。detect有一个参数,要求是bytes类型。bytes类型可以通过读取网页内容、open函数的rb模式、带b前缀的字符串、encode函数等途径获得。

示例代码:

1
2
3
4
5
6
7
8
9
import chardet
some_string = '你好,世界。'.encode('utf-8'# encode方法返回一个bytes
# b'\xe4\xbd\xa0\xe5\xa5\xbd\xef\xbc\x8c\xe4\xb8\x96\xe7\x95\x8c\xe3\x80\x82'
result = chardet.detect(some_string) # 调用检测接口
print(result)
# {'encoding': 'utf-8', 'confidence': 0.99}

如上所示,detect函数返回一个字典,字典里有两个key-value对。其中一个的key值为encoding,代表chardet推断出来的编码格式。另一个key值为confidence,代表可信度。可信度是一个0到1之间float值,0代表不可信,1代表百分之百可信。


高级用法

当用于检测的文档特别大时,可以chardet的子模块chardet.universaldetector。这个模块允许我们分多次(逐行读取或者自行断行读取)检测文本的编码格式,当达到一定的阈值时便可以提前退出检测。这样做可以有效地节省资源,提高程序效率,同时保证检测结果的准确性。

示例代码:

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from chardet.universaldetector import UniversalDetector
detector = UniversalDetector() # 初始化一个UniversalDetector对象
= open('test.txt''rb'# test.txt是一个utf-8编码的文本文档
for line in f:
    detector.feed(line) # 逐行载入UniversalDetector对象中进行识别
    if detector.done: # done为一个布尔值,默认为False,达到阈值时变为True
        break
detector.close() # 调用该函数做最后的数据整合
f.close()
print(detector.result)
# {'confidence': 1.0, 'encoding': 'UTF-8-SIG'}

需要注意的是:如果对多个不同来源的文本进行检测,在每次检测完毕时,必须调用一次UniversalDetector对象的reset函数,将之前的检测数据清除。否则会导致后面的检测结果混乱。


目前支持的编码格式

Universal Encoding Detector目前支持以下编码格式:

  • Big5, GB2312/GB18030, EUC-TW, HZ-GB-2312, and ISO-2022-CN (Traditional and Simplified – Chinese 繁体和简体中文)
  • EUC-JP, SHIFT_JIS, and ISO-2022-JP (Japanese 日文)
  • EUC-KR and ISO-2022-KR (Korean 韩文)
  • KOI8-R, MacCyrillic, IBM855, IBM866, ISO-8859-5, and windows-1251 (Russian 俄文)
  • ISO-8859-2 and windows-1250 (Hungarian 匈牙利文)
  • ISO-8859-5 and windows-1251 (Bulgarian 保加利亚文)
  • ISO-8859-1 and windows-1252 (Western European languages 西欧文字)
  • ISO-8859-7 and windows-1253 (Greek 希腊文)
  • ISO-8859-8 and windows-1255 (Visual and Logical Hebrew 视觉顺序和逻辑顺序的希伯来文)
  • TIS-620 (Thai 泰文)
  • UTF-32 BE, LE, 3412-ordered, or 2143-ordered (with a BOM 带字节序标记)
  • UTF-16 BE or LE (with a BOM 带字节序标记)
  • UTF-8 (with or without a BOM 带或者不带字节序标记)
  • ASCII

注意:由于内部的相似性,某些情况下会出现检测错误。最常出问题的是匈牙利文,会出现报告的编码是两种之中的另一种。希腊文的检测也经常错误的将ISO-8859-7识别为匈牙利文的ISO-8859-2。


关于检测时出现的奇怪错误

该模块在检测ANSI编码(在中文版windows系统上就是gbk)的时候会出现一些奇怪的错误,博主正在研究英文文档,希望能在上面找到答案。如果有后续,会同步更新至本文。

接上文:

问题来源:某些情况下检测ANSI编码的文本文档和gb2312编码的字节包会出现错误。

过程:博主分别对不同情况下录入、不同长度和不同编码的字节包进行了测试。并仔细看了一遍官方文档。大概理出了个思路。

解析:官方文档上有一段话,我先原文摘下来。

If UniversalDetector detects a high-bit character in the text, but none of the other multi-byte or single-byte encoding probers return a confident result, it creates a Latin1Prober (defined in latin1prober.py) to try to detect English text in a windows-1252 encoding. This detection is inherently unreliable, because English letters are encoded in the same way in many different encodings. The only way to distinguish windows-1252 is through commonly used symbols like smart quotes, curly apostrophes, copyright symbols, and the like. Latin1Prober automatically reduces its confidence rating to allow more accurate probers to win if at all possible.

大概意思是,当UniversalDetector在解析一些字节的时候,如果没有相应的探测器给出报告,它就会调用一个叫做Latin1Prober的探测器试图用英文编码windows-1252来解析该字节包,这个探测器非常不可信(官方吐槽…)。通常情况下英文字母和一些特殊符号在不同的编码里是一样的,所以这个探测器会给出很高的可信度。这个探测器会自动地压低自己给出的可信度以让其他探测器可以优先通过。

再根据以下这段原文:

The main entry point for the detection algorithm is universaldetector.py, which has one class, UniversalDetector. (You might think the main entry point is the detect function in chardet/init.py, but that’s really just a convenience function that creates a UniversalDetector object, calls it, and returns its result.)

大概是这样的:检测算法的入口是UniversalDetector,而chardet.detect函数只是语法上的甜点,用户很容易使用。
可能会发现detect函数中也出现了类似的机制。虽然Latin1Prober已经进行了优化,但在某些情况下,它的可信度仍然远远超出实际水平。例如,以下实验:
blogger还做了一些其他的实验,并得出一个结论:当字节包不够长时,chardet给出的结论是非常不可靠的,因为它可能会在调用一个不相关的探测器时,给出一个超出阈值的可信度,或者两个编码格式正好是共通的字符,然后就不再往下检测了。这样做很容易产生不可靠的测试结果。因此最好不检测非常少量的字节。与此同时,在检测具有较长字符开头的文档时,最好首先手工删除无关符号(因为程序会根据初始遍历结果对检测器进行优先排序,但保证不准会出错),这样就不会出现错误,从而得到最精确的结果。
此网址详细说明了HowUniversalEncodingDetectorWorks模块的工作方式。推荐能够读英文且有耐心的读者进行阅读。博客只是有选择地快速读了一遍,并不能保证将原作者的意思传达给大家,但也可以保证偏差不会太大。



浅谈SEO数据监控

绝大部分的SEOer都没有对网站专门的做数据监控的,大部分的情况下都只是利用第三方方的站长工具查看一下数据就完事。比如看看权重是不是上升了,看看关键词有没有上涨等等。平时的时候也是偶尔看看,只有出现重大问题的时候才会去关注这个数据的成长历程,然而一般这种情况下都比较难对数据进行追溯。

阅读更多