更新時間:2024-10-01 20:07:52作者:佚名
chardet的使用非常簡單。主模塊中只有一個檢測功能。 detector 有一個參數,要求其類型為 bytes。 bytes類型可以通過讀取網頁內容、open函數的rb模式、b前綴的字符串、encode函數等獲取。
示例代碼:
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}
如上所示,檢測函數返回一個包含兩個鍵值對的字典。其中之一的鍵值是encoding,表示chardet推斷的編碼格式。另一個關鍵價值是信心,它代表可信度??尚哦仁?0 到 1 之間的浮點值,0 表示不可信,1 表示 100% 可信。
高級用法
當用于檢測的文檔特別大時使用方法的英文,可以使用chardet的子模塊chardet.universal detector。該模塊允許我們多次檢測文本的編碼格式(逐行讀取或逐行讀取),并在達到一定閾值時提前退出檢測。這樣可以有效節省資源,提高程序效率,保證測試結果的準確性。
示例代碼:
from chardet.universaldetector import UniversalDetector
detector = UniversalDetector() # 初始化一個UniversalDetector對象
f = 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函數,以清除之前的檢測數據。否則,后續的測試結果將會混亂。
目前支持的編碼格式
通用編碼檢測器目前支持以下編碼格式:
注:由于內部相似性,在某些情況下可能會出現檢測錯誤。最常見的問題是匈牙利語,報告的編碼是兩者中的另一個。希臘語檢測也經常將 ISO-8859-7 錯誤地識別為匈牙利語 ISO-8859-2。
關于檢測過程中出現的奇怪錯誤
該模塊在檢測ANSI編碼(中文版Windows系統上為gbk)時會出現一些奇怪的錯誤。博主正在研究英文文檔,希望能在那里找到答案。如有后續,本文將同步更新。
從上面繼續:
問題根源:某些情況下,檢測ANSI編碼的文本文檔和gb2312編碼的字節包時可能會出現錯誤。
過程:博主測試了不同情況下輸入的字節包網校頭條,不同長度,不同編碼。并仔細閱讀官方文檔。我大概想出了一個主意。
分析:官方文檔中有一段話,我先從原文中摘錄一下。
如果 UniversalDetector 檢測到文本中的高位字符,但其他多字節或單字節編碼探測器都沒有返回可信結果,它會創建一個 Latin1Prober(在 latin1prober.py 中定義)來嘗試檢測windows-1252 編碼。這種檢測本質上是不可靠的,因為英文字母在許多不同的編碼中都以相同的方式進行編碼。區分 windows-1252 的唯一方法是通過常用的符號,例如智能引號、彎撇號、版權符號等。 Latin1Prober 會自動降低其置信度,以便盡可能讓更準確的探測器獲勝。
大致意思是,當UniversalDetector解析某些字節時,如果沒有相應的檢測器給出報告,它會調用一個名為Latin1Prober的檢測器來嘗試使用英文編碼windows-1252來解析該字節包。這個檢測設備非常不可信(官方投訴……)。通常英文字母和一些特殊符號在不同的編碼中是相同的,因此該檢測器會給出很高的置信度。該檢測器將自動降低其置信度,以允許其他檢測器先通過。
根據以下原文:
檢測算法的主要入口點是universalDetector.py,它有一個類,UniversalDetector。 (您可能認為主要入口點是 chardet/init.py 中的檢測函數,但這實際上只是一個創建 UniversalDetector 對象、調用它并返回其結果的便利函數。)
大致意思是:檢測算法的入口是UniversalDetector,chardet.detect函數只是方便用戶使用的語法糖。
可以推斷,類似的機制也會出現在 detector 函數中。盡管 Latin1Prober 已經過優化,但在某些情況下,它給出的置信度仍然比實際情況高得多。例如這個實驗:
博主還做了其他幾個實驗,得出了一個結論:當字節包的長度不夠長時,chardet給出的結論非常不可靠,因為它可能會調用一個不相關的檢測器。 ,檢測器給出的置信度超過閾值,或者兩種編碼格式恰好有共同的字符,則不再進行進一步的檢測。這樣做很容易導致測試結果不可靠。因此最好不要檢測非常少量的字節。同時,當檢測到開頭有大段其他字符的文檔時,最好先手動處理不相關的符號(可能不會出現錯誤,因為程序會根據檢測器的順序來優先排序)初始遍歷的結果,但不能保證可能會出現錯誤)以獲得最準確的結果。
通用編碼檢測器的工作原理詳細解釋了該模塊的工作原理。建議懂英文并有耐心的讀者讀完。博主只是選擇性地、快速地閱讀了它。我不能保證將原作者的意思傳達給你,但我也可以保證偏差不會太大。
支持原創-->原文鏈接