入坑-乱码

关于爬虫乱码有很多各式各样的问题,这里不仅是中文乱码,编码转换、还包括一些如日文、韩文 、俄文、藏文之类的乱码处理,因为解决方式是一致的,故在此统一说明。

网络爬虫出现乱码的原因

源网页编码和爬取下来后的编码格式不一致。

如源网页为gbk编码的字节流,而我们抓取下后程序直接使用utf-8进行编码并输出到存储文件中,这必然会引起乱码即当源网页编码和抓取下来后程序直接使用处理编码一致时,则不会出现乱码;此时再进行统一的字符编码也就不会出现乱码了

注意区分

  • 源网编码A、

  • 程序直接使用的编码B、

  • 统一转换字符的编码C。

乱码的解决方法

确定源网页的编码A,编码A往往在网页中的三个位置

  • http header的Content-Type

获取服务器 header 的站点可以通过它来告知浏览器一些页面内容的相关信息。Content-Type 这一条目的写法就是 "text/html; charset=utf-8"。入坑-乱码编码 - 图1

  • meta charset
  1. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  • 网页头中Document定义
  1. <script type="text/javascript">
  2. if(document.charset){
  3. alert(document.charset+"!!!!");
  4. document.charset = 'GBK';
  5. alert(document.charset);
  6. }
  7. else if(document.characterSet){
  8. alert(document.characterSet+"????");
  9. document.characterSet = 'GBK';
  10. alert(document.characterSet);
  11. }

在获取源网页编码时,依次判断下这三部分数据即可,从前往后,优先级亦是如此。

Python chardet 字符编码判断

使用 chardet 可以很方便的实现字符串/文件的编码检测虽然HTML页面有charset标签,但是有些时候是不对的。那么chardet就能帮我们大忙了。

chardet实例

  1. import urllib
  2. rawdata = urllib.urlopen('http://www.jb51.net/').read()
  3. import chardet
  4. chardet.detect(rawdata)
  5. {'confidence': 0.99, 'encoding': 'GB2312'}

chardet可以直接用detect函数来检测所给字符的编码。函数返回值为字典,有2个元素,一个是检测的可信度,另外一个就是检测到的编码。

在开发自用爬虫过程中如何处理汉字编码?

下面所说的都是针对python2.7,如果不加处理,采集到的都是乱码,解决的方法是将html处理成统一的utf-8编码遇到windows-1252编码,属于chardet编码识别训练未完成

  1. import chardet
  2. a='abc'
  3. type(a)
  4. str
  5. chardet.detect(a)
  6. {'confidence': 1.0, 'encoding': 'ascii'}
  7. a ="我"
  8. chardet.detect(a)
  9. {'confidence': 0.73, 'encoding': 'windows-1252'}
  10. a.decode('windows-1252')
  11. u'\xe6\u02c6\u2018'
  12. chardet.detect(a.decode('windows-1252').encode('utf-8'))
  13. type(a.decode('windows-1252'))
  14. unicode
  15. type(a.decode('windows-1252').encode('utf-8'))
  16. str
  17. chardet.detect(a.decode('windows-1252').encode('utf-8'))
  18. {'confidence': 0.87625, 'encoding': 'utf-8'}
  19. a ="我是中国人"
  20. type(a)
  21. str
  22. {'confidence': 0.9690625, 'encoding': 'utf-8'}
  23. chardet.detect(a)
  1. # -*- coding:utf-8 -*-
  2. import chardet
  3. import urllib2
  4. #抓取网页html
  5. html = urllib2.urlopen('http://www.jb51.net/').read()
  6. print html
  7. mychar=chardet.detect(html)
  8. print mychar
  9. bianma=mychar['encoding']
  10. if bianma == 'utf-8' or bianma == 'UTF-8':
  11. html=html.decode('utf-8','ignore').encode('utf-8')
  12. else:
  13. html =html.decode('gb2312','ignore').encode('utf-8')
  14. print html
  15. print chardet.detect(html)

python代码文件的编码

py文件默认是ASCII编码,中文在显示时会做一个ASCII到系统默认编码的转换,这时就会出错:SyntaxError: Non-ASCII character。需要在代码文件的第一行添加编码指示:

  1. # -*- coding:utf-8 -*-
  2. print '中文'

像上面那样直接输入的字符串是按照代码文件的编码'utf-8'来处理的

如果用unicode编码,以下方式:

  1. s1 = u'中文' #u表示用unicode编码方式储存信息

decode是任何字符串具有的方法,将字符串转换成unicode格式,参数指示源字符串的编码格式。

encode也是任何字符串具有的方法,将字符串转换成参数指定的格式。