更新時(shí)間:2024-10-01 20:12:16作者:佚名
chardet的使用非常簡(jiǎn)單。主模塊中只有一個(gè)檢測(cè)功能。 detector 有一個(gè)參數(shù),要求其類型為 bytes。 bytes類型可以通過(guò)讀取網(wǎng)頁(yè)內(nèi)容、open函數(shù)的rb模式、b前綴的字符串、encode函數(shù)等獲取。
示例代碼:
import chardet
some_string = '你好,世界。'.encode('utf-8') # encode方法返回一個(gè)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) # 調(diào)用檢測(cè)接口
print(result)
# {'encoding': 'utf-8', 'confidence': 0.99}
如上所示,檢測(cè)函數(shù)返回一個(gè)包含兩個(gè)鍵值對(duì)的字典。其中之一的鍵值是encoding,表示chardet推斷的編碼格式。另一個(gè)關(guān)鍵價(jià)值是信心,它代表可信度。可信度是 0 到 1 之間的浮點(diǎn)值,0 表示不可信,1 表示 100% 可信。
高級(jí)用法
當(dāng)用于檢測(cè)的文檔特別大時(shí)使用方法的英文,可以使用chardet的子模塊chardet.universal detector。該模塊允許我們多次檢測(cè)文本的編碼格式(逐行讀取或逐行讀取),并在達(dá)到一定閾值時(shí)提前退出檢測(cè)。這樣可以有效節(jié)省資源,提高程序效率,保證測(cè)試結(jié)果的準(zhǔn)確性。
示例代碼:
from chardet.universaldetector import UniversalDetector
detector = UniversalDetector() # 初始化一個(gè)UniversalDetector對(duì)象
f = open('test.txt', 'rb') # test.txt是一個(gè)utf-8編碼的文本文檔
for line in f:
detector.feed(line) # 逐行載入U(xiǎn)niversalDetector對(duì)象中進(jìn)行識(shí)別
if detector.done: # done為一個(gè)布爾值,默認(rèn)為False,達(dá)到閾值時(shí)變?yōu)門rue
break
detector.close() # 調(diào)用該函數(shù)做最后的數(shù)據(jù)整合
f.close()
print(detector.result)
# {'confidence': 1.0, 'encoding': 'UTF-8-SIG'}
需要注意的是使用方法的英文,如果檢測(cè)到來(lái)自多個(gè)不同來(lái)源的文本,則每次檢測(cè)完成后都必須調(diào)用一次UniversalDetector對(duì)象的reset函數(shù),以清除之前的檢測(cè)數(shù)據(jù)。否則,后續(xù)的測(cè)試結(jié)果將會(huì)混亂。
目前支持的編碼格式
通用編碼檢測(cè)器目前支持以下編碼格式:
注:由于內(nèi)部相似性,在某些情況下可能會(huì)出現(xiàn)檢測(cè)錯(cuò)誤。最常見的問(wèn)題是匈牙利語(yǔ),報(bào)告的編碼是兩者中的另一個(gè)。希臘語(yǔ)檢測(cè)也經(jīng)常將 ISO-8859-7 錯(cuò)誤地識(shí)別為匈牙利語(yǔ) ISO-8859-2。
關(guān)于檢測(cè)過(guò)程中出現(xiàn)的奇怪錯(cuò)誤
該模塊在檢測(cè)ANSI編碼(中文版Windows系統(tǒng)上為gbk)時(shí)會(huì)出現(xiàn)一些奇怪的錯(cuò)誤。博主正在研究英文文檔,希望能在那里找到答案。如有后續(xù),本文將同步更新。
從上面繼續(xù):
問(wèn)題根源:某些情況下,檢測(cè)ANSI編碼的文本文檔和gb2312編碼的字節(jié)包時(shí)可能會(huì)出現(xiàn)錯(cuò)誤。
過(guò)程:博主測(cè)試了不同情況下輸入的字節(jié)包網(wǎng)校頭條,不同長(zhǎng)度,不同編碼。并仔細(xì)閱讀官方文檔。我大概想出了一個(gè)主意。
分析:官方文檔中有一段話,我先從原文中摘錄一下。
如果 UniversalDetector 檢測(cè)到文本中的高位字符,但其他多字節(jié)或單字節(jié)編碼探測(cè)器都沒(méi)有返回可信結(jié)果,它會(huì)創(chuàng)建一個(gè) Latin1Prober(在 latin1prober.py 中定義)來(lái)嘗試檢測(cè)windows-1252 編碼。這種檢測(cè)本質(zhì)上是不可靠的,因?yàn)橛⑽淖帜冈谠S多不同的編碼中都以相同的方式進(jìn)行編碼。區(qū)分 windows-1252 的唯一方法是通過(guò)常用的符號(hào),例如智能引號(hào)、彎撇號(hào)、版權(quán)符號(hào)等。 Latin1Prober 會(huì)自動(dòng)降低其置信度,以便盡可能讓更準(zhǔn)確的探測(cè)器獲勝。
大致意思是,當(dāng)UniversalDetector解析某些字節(jié)時(shí),如果沒(méi)有相應(yīng)的檢測(cè)器給出報(bào)告,它會(huì)調(diào)用一個(gè)名為L(zhǎng)atin1Prober的檢測(cè)器來(lái)嘗試使用英文編碼windows-1252來(lái)解析該字節(jié)包。這個(gè)檢測(cè)設(shè)備非常不可信(官方投訴……)。通常英文字母和一些特殊符號(hào)在不同的編碼中是相同的,因此該檢測(cè)器會(huì)給出很高的置信度。該檢測(cè)器將自動(dòng)降低其置信度,以允許其他檢測(cè)器先通過(guò)。
根據(jù)以下原文:
檢測(cè)算法的主要入口點(diǎn)是universalDetector.py,它有一個(gè)類,UniversalDetector。 (您可能認(rèn)為主要入口點(diǎn)是 chardet/init.py 中的檢測(cè)函數(shù),但這實(shí)際上只是一個(gè)創(chuàng)建 UniversalDetector 對(duì)象、調(diào)用它并返回其結(jié)果的便利函數(shù)。)
大致意思是:檢測(cè)算法的入口是UniversalDetector,chardet.detect函數(shù)只是方便用戶使用的語(yǔ)法糖。
可以推斷,類似的機(jī)制也會(huì)出現(xiàn)在 detector 函數(shù)中。盡管 Latin1Prober 已經(jīng)過(guò)優(yōu)化,但在某些情況下,它給出的置信度仍然比實(shí)際情況高得多。例如這個(gè)實(shí)驗(yàn):
博主還做了其他幾個(gè)實(shí)驗(yàn),得出了一個(gè)結(jié)論:當(dāng)字節(jié)包的長(zhǎng)度不夠長(zhǎng)時(shí),chardet給出的結(jié)論非常不可靠,因?yàn)樗赡軙?huì)調(diào)用一個(gè)不相關(guān)的檢測(cè)器。 ,檢測(cè)器給出的置信度超過(guò)閾值,或者兩種編碼格式恰好有共同的字符,則不再進(jìn)行進(jìn)一步的檢測(cè)。這樣做很容易導(dǎo)致測(cè)試結(jié)果不可靠。因此最好不要檢測(cè)非常少量的字節(jié)。同時(shí),當(dāng)檢測(cè)到開頭有大段其他字符的文檔時(shí),最好先手動(dòng)處理不相關(guān)的符號(hào)(可能不會(huì)出現(xiàn)錯(cuò)誤,因?yàn)槌绦驎?huì)根據(jù)檢測(cè)器的順序來(lái)優(yōu)先排序)初始遍歷的結(jié)果,但不能保證可能會(huì)出現(xiàn)錯(cuò)誤)以獲得最準(zhǔn)確的結(jié)果。
通用編碼檢測(cè)器的工作原理詳細(xì)解釋了該模塊的工作原理。建議懂英文并有耐心的讀者讀完。博主只是選擇性地、快速地閱讀了它。我不能保證將原作者的意思傳達(dá)給你,但我也可以保證偏差不會(huì)太大。
支持原創(chuàng)-->原文鏈接