zoukankan      html  css  js  c++  java
  • 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是个很不错的选择。

  • 相关阅读:
    MongoDB-JAVA-Driver 3.2版本常用代码全整理(4)
    MongoDB-JAVA-Driver 3.2版本常用代码全整理(3)
    MongoDB-JAVA-Driver 3.2版本常用代码全整理(2)
    MongoDB-JAVA-Driver 3.2版本常用代码全整理(1)
    c++清除输入缓冲区之 sync() vs ignore()
    typedef 类型重命名 和 #define 宏定义(1)
    从gcc的__attribute__((packed))聊到结构体大小的问题
    对于volatile的理解
    把一个string串的所有小写字母转成大写字母的例子来看看看全局函数的使用
    string与char* 互相转换以及周边问题
  • 原文地址:https://www.cnblogs.com/traditional/p/11877591.html
Copyright © 2011-2022 走看看