小甲鱼 发表于 2015-11-8 03:07:29

一次性解决你所有的编码检测问题

在日常使用中,我们难以避免会遇到编码转换问题。(如果编码是什么都不知道,请先看:什么是编码?)

而进行编码转换的前提是你知道这个字符串使用的是什么编码。

比如你使用 urllib.request.urlopen() 获取一个网页时,你特么如果不知道网页的编码会怎样?


直接 read().decode() 就可能会出现下边错误:



这是因为无论是 encode() 还是 decode(),默认采取的编码/解码都是 encoding="utf-8" 编码……

虽然你大 UTF-8 行迹踏遍天下,但在这神州大地,处处都有奇葩的好不?


这时候需要一个可靠的方式来检测字符串到底是什么编码,这样我们才能对症下药!


这里小甲鱼向大家推荐一个不错的模块:chardet,使用它就可以检测字符串的编码。

chardet 模块可以检测以下编码:


[*]ASCII, UTF-8, UTF-16 (2 variants), UTF-32 (4 variants)
[*]Big5, GB2312, EUC-TW, HZ-GB-2312, ISO-2022-CN (Traditional and Simplified Chinese)
[*]EUC-JP, SHIFT_JIS, CP932, ISO-2022-JP (Japanese)
[*]EUC-KR, ISO-2022-KR (Korean)
[*]KOI8-R, MacCyrillic, IBM855, IBM866, ISO-8859-5, windows-1251 (Cyrillic)
[*]ISO-8859-2, windows-1250 (Hungarian)
[*]ISO-8859-5, windows-1251 (Bulgarian)
[*]windows-1252 (English)
[*]ISO-8859-7, windows-1253 (Greek)
[*]ISO-8859-8, windows-1255 (Visual and Logical Hebrew)
[*]TIS-620 (Thai)


chardet 模块安装方法:

1. (推荐)使用 pip 安装,打开命令行窗口(Windows 的 cmd,Linux 的 terminal,Mac 的“终端”)

输入命令:pip install chardet




2. 下载安装包并解压:

打开命令行窗口(同上),切换目录到上方解压包的文件夹,输入命令:C:\Python34\python.exe setup.py install




chardet 模块用法:

非常简单,使用该模块的 detect() 函数即可:
>>> import urllib.request
>>> response = urllib.request.urlopen("http://bbs.fishc.com").read()
>>> import chardet
>>> chardet.detect(response)
{'confidence': 0.99, 'encoding': 'GB2312'}
哦,confidence 是可信度的意思……

0.99 就是 99% 确定是 'GB2312'!

年轻人,你太傲娇了,偶其实使用的是 GBK 编码(GBK 是 GB2312 的扩展)



所以你直接 decode('GB2312') 还是会报错的:
>>> response.decode("GB2312")
Traceback (most recent call last):
File "<pyshell#41>", line 1, in <module>
    response.decode("GB2312")
UnicodeDecodeError: 'gb2312' codec can't decode byte 0xfd in position 22581: illegal multibyte sequence

你现在有两种选择:

一、忽略识别不出的字符(GB2312 支持的汉字比较少,如果用这种方法会出现小部分乱码)

>>> response.decode("GB2312", "ignore")
……
<ul><li># <a href="thread-64400-1-1.html" title="乔布斯最精彩演讲:这三个故事决定了我的一生" target="_blank">乔布斯最精彩演讲:这三个故事决定了我的一</a></li><li># <a href="thread-50608-1-1.html" title="42个锻炼大脑的方法,你想不聪明都不行!" target="_blank">42个锻炼大脑的方法,你想不聪明都不行!</a></li><li># <a href="thread-23917-1-1.html" title="潘靠赐辏泪流满面(转)" target="_blank">潘靠赐辏泪流满面(转)</a>
……

二、(推荐)由于 GBK 是向下兼容 GB2312,因此你检测到是 GB2312,则直接用 GBK 来编码/解码

>>> if chardet.detect(response)['encoding'] == 'GB2312':
      response.decode('GBK')
……
<ul><li># <a href="thread-64400-1-1.html" title="乔布斯最精彩演讲:这三个故事决定了我的一生" target="_blank">乔布斯最精彩演讲:这三个故事决定了我的一</a></li><li># <a href="thread-50608-1-1.html" title="42个锻炼大脑的方法,你想不聪明都不行!" target="_blank">42个锻炼大脑的方法,你想不聪明都不行!</a></li><li># <a href="thread-23917-1-1.html" title="屌丝看完,泪流满面(转)" target="_blank">屌丝看完,泪流满面(转)
……

caopeirui 发表于 2015-11-8 18:28:17

甲鱼哥给力

无名似名 发表于 2015-11-9 15:58:57

学习了

瞬秒爆加速 发表于 2015-11-10 15:39:53

觉得只提供了些资源而已,还是要通过自身的判断。。。

wing1995 发表于 2015-11-16 20:51:11

然而,encode的时候出问题了:

红枫 发表于 2015-11-30 20:35:29

谢谢小甲鱼!

Jx0101 发表于 2016-3-2 11:49:01

我早看到就好了,之前写爬虫的时候各种编码问题{:10_266:}

VVFock3r 发表于 2016-3-2 11:51:17

竞技山 发表于 2016-7-19 17:30:30

学习了

sunfore 发表于 2016-7-19 18:39:35

学习了

gaomengsuijia 发表于 2016-7-20 14:02:52

>>> file = rq.urlopen("http://www.sina.com")
>>> html = file.read()
>>> chardet.detect(html)
{'confidence': 0.0, 'encoding': None}
检查新浪的网页编码,为啥是None,而且可信度为0
甲鱼哥哥,这是为啥了

18191171661 发表于 2016-7-27 12:38:41

楼主,您好:
      我就按照第二个方法安装的chardet,而且安装成功,刚开始可以导入到python里,当我重新打开IDLE时,import chardet,显示不存在,请问这是什么原因?谢谢大家

小菜鸟翻身 发表于 2016-7-27 16:22:57

坏小子 发表于 2016-7-29 14:06:53

学习啦,之前写爬虫可是为了这个编码问题头疼半天了{:10_254:}

haizi865 发表于 2016-8-2 10:21:57

学习到了!{:10_277:}

sevin 发表于 2016-8-16 21:24:44

很有帮助

goodgrape 发表于 2016-9-16 10:16:21

Python 神奇的地方真是太多!

浅葱白雪 发表于 2016-9-21 16:00:14

赞一个

一刀封喉 发表于 2016-12-1 11:42:40

灰常棒棒哒

流月飞星 发表于 2016-12-22 23:04:42

厉害了{:10_266:}
页: [1] 2 3 4 5
查看完整版本: 一次性解决你所有的编码检测问题