chardet:字符編碼探測器,自動檢測文本、網頁、xml的編碼


楔子

在請求數據的時候,我們得到的可能是一堆字節,這個時候我們會通過decode將其解碼。但是解碼的前提是我們需要知道其對應編碼是什么,比如:utf-8iso-8859-1gbk等等。而python也提供了相應的模塊,用於檢測字節對應的編碼。

chardet檢測編碼

from chardet import detect

# 直接傳入字節即可
print(detect(b"are you ok?"))  # {'encoding': 'ascii', 'confidence': 1.0, 'language': ''}
"""
可以看到返回一個字典,包含三個key:
encoding: 使用的編碼
confidence: 檢測的准確度
language: 所使用的語言
"""

對於其它語言也是支持的

from chardet import detect

chinese_utf8 = "你為什么這么熟練啊".encode("utf-8")
chinese_gbk = "你為什么這么熟練啊".encode("gbk")
print(detect(chinese_utf8))  
# {'encoding': 'utf-8', 'confidence': 0.99, 'language': ''}

print(detect(chinese_gbk))  
# {'encoding': 'GB2312', 'confidence': 0.8888888888888888, 'language': 'Chinese'}

我們看到當使用utf-8編碼的時候,雖然能檢測出編碼,但是無法推測出語言,因為任何語言的字符都可以正常使用utf-8進行編碼。但是下面的gbk是可以推斷出語言的,因為這是專門用於中文的編碼,顯示的gb2312是gbk的子集。

from chardet import detect

jp_utf8 = "なんでそんなに慣れてんだよ".encode("utf-8")
jp_euc = "なんでそんなに慣れてんだよ".encode("euc-jp")
print(detect(jp_utf8))
# {'encoding': 'utf-8', 'confidence': 0.99, 'language': ''}

print(detect(jp_euc))
# {'encoding': 'EUC-JP', 'confidence': 1.0, 'language': 'Japanese'}

對於日文也是一樣的,chardet支持多種語言。

尤其是向其它地方請求數據的時候,給你返回了一堆你不知道是什么編碼的字節,這個時候就可以使用chardet,最典型的就是requests。

我們在使用requests的get方法之后,會調用text得到請求的html。但是有時候調用text返回的內容里面包含亂碼,這是因為requests在內部是先獲取的字節,然后再進行解碼、返回,而在解碼的時候,使用了錯誤的編碼造成的

而一般我們在調用text之前,我們會手動指定使用的編碼

import requests

res = requests.get("http://www.baidu.com")
# res.content: 會拿到html對應的字節流
# res.encoding: 所使用的編碼,根據網站決定
# res.text: 會先獲取res.content,然后通過res.encoding進行解碼得到res.txt

# 但是默認的res.encoding不一定能夠正常解碼,這個時候我們會手動指定res.encoding
# 將res.apparent_encoding賦值給res.encoding
res.encoding = res.apparent_encoding
# 然后調用res.text就能正常打印內容了
print(res.text)

那么我們就可以進入源碼中看看這個res.apparent_encoding是什么

    @property
    def apparent_encoding(self):
        """The apparent encoding, provided by the chardet library."""
        return chardet.detect(self.content)['encoding']

看到了嗎?requests也是通過chardet檢測對應的編碼的,因為requests默認使用網站返回的編碼,但是不一定靠譜。而通過這一步,會根據返回的字節手動推斷出其使用的編碼,然后賦值給res.encoding,這樣再解碼就沒有問題了。

因此想知道返回的字節是什么編碼的話,使用chardet是個很不錯的選擇。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM