关于爬虫字符集不匹配问题的解决办法
背景
由于世界上语言各异,进行信息爬取的过程中,难免遇到各种各样奇怪的字符,导致我们进行持久化时遇到困难。
今天在写爬虫时就遇到了一个’gbk’编码集无法解析的字符:‘\u2022’
该字符使用正确编码时,在显示器上显示的应为•
然而我们先要知道该字符是来自于哪一字符集较为困难,那有没有什么直接使用原网页字符集的方法呢?
查看原网页字符集
查看原网站编码集的方法有很多,比如通过console输入:
1 | document.charset //'GBK' |
或者直接查看网页的如下标签:
1 | <meta http-equiv="Content-Type" content="text/html;charset=gbk"> |
然而这通常只能知道该网页是使用某种gbk编码编制的。让然不够准确,而且需要我么切到浏览器进行操作,这有可能打断我们编码的思路。
chardet模块
另一种更好的方法是使用python的chardet库。
chardet为我们提供了一种网络资源编码方式自动检测的方案。
该模块的作者实际上是将Mozilla的自动编码检测技术封装成了接口 the auto-detection code in Mozilla
对原算法感兴趣的话可以阅读如下论文A composite approach to language/encoding detection (mozilla.org)
detect()
chardet最常用的使用方式就是:
1 | import urllib.request |
这样就能直接获取某一整篇文本的编码方式。
该方法接收一个non-Unicode
字符串作为参数,并且返回该字符串最有可能使用的字符集,以及推测使用该字符集的概率confidence
,该值是一个0-1之间的数。
UniversalDetector
而当我们面对一个非常长的文本时,直接传入正片文本会导致算法推断的事件过长。
试该接口为我们提供了一个UniversalDetector类,该类包含一个feed
方法,接受一个字符串,用于推断,一个done
属性,用于检测推断的字符集的置信度是否已经到达了推断的最低门槛,到达最低门槛时,该对象将会吧done
值置为true
在分析完全部分当时,请调用close
方法,因为该方法会进行最后的计算,以应对没有任何一个可能的字符集的置信度达到最低门槛的情况。
最后result
属性将是一个包含了可能的字符集与置信度的dictionary
1 | import urllib.request |
多文档分析
如果需要对多个文本进行字符集预测,则可以使用同一个UniversalDetector
类,并在对每个文档进行预测前使用reset
方法。
1 | import glob |