原文地址:
http://blog.chinaunix.net/uid-12014716-id-4341820.html
我要从小白做起。
第一步:你需要知道你所抓取的网页编码格式,方法:右键查看网页编码,ctrl +F ,搜索:charset
会看到:<meta http-equiv="Content-Type" content="text/html; charset=gbk" />,OK确定是gbk编码格式了;
为什么会提到编码,这里大概讲讲原理:
我们看到的所有字符,在计算机里面都是用01010101二进制编码,然后你要想在屏幕上看到ABCD,计算机需要指定某个特定的二进制串来对应ABCD,比如A是011,0100是B等,每个字母都代表一个独有的二进制串,起初计算机是美国人发明了,他们只考虑了0-9a-zA-Z以及一些简单符号,这些符号等用一个字节(8位)的二进制串就能代表全了,这就是所谓的ASCII编码,然而一个字节有2的8次方大小的容量,随着科技的发展,计算机遍及了世界,ASCII编码已经满足不了,所以后来中国、印度等其他国家自己制定了一套编码规则,才诞生的GBK等等一系列的编码,但是还不够统一,不可避免地出现冲突,结果就是,在多语言混合的文本中,显示出来会有乱码,于是有人发明了一种万能的编码,unicode,一次性将全世界各种语言编码情况都包含进来了。
ASCII编码是1个字节,Unicode编码是2个字节;但是问题出来了,乱码是没了,但是如果你处理的文本中包含有大量的英文字符,用unicode编码要多占一半的空间,所以本着节约精神,UTF-8编码应运而生,UTF-8可变长编码把一个Unicode字符根据不同的数字大小编码成1-6个字节,常用的英文字母被编码成1个字节,汉字通常是3个字节,只有很生僻的字符才会被编码成4-6个字节。如果你要传输的文本包含大量英文字符,用UTF-8编码就能节省空间;所以我们可以这样理解:gbk和utf-8等编码格式就是unicode编码的子集,对其他任意格式的字符串进行解码操作都是让他们成为unicode编码,然后能随便你指定编码类型了,将它转了gbk也行,utf8也行。
而这里,为什么那么多人的电脑可能打印出来的中文不同呢,例如print '中国',有些人是直接展示编码,有些人是直接展示中文,这是跟他当时环境息息相关的,比如sublime默认的编码格式是utf-8,cmd默认是gbk编码等等,下面会讲到原因;
继续开始讲网页抓取,要查看编码格式,发现是gbk格式的,抓取时候,你的python系统是不认识,你的sublime系统也是不认识的,这里就需要把gbk格式解码成系统认识的unicode编码,解码方式:a.decode('gbk'),他的意思是对a这个字符串根据gbk的形式进行解码为unicode,注意这里是如果你打印出来,不一定就是你想要的中文,还需要指定编码格式,a.encode('gbk')的意思是对a这个字符串gbk编码,上面提到这个a字符串必须是unicode编码前提下才能encode;encode后就会按照你想要的编码格式输出了。如果你用cmd调试,可以不用加上encode,因为cmd默认的编码格式是gbk了,但你用sublime就不一定了,所以跟系统环境关系很大的。
这里通俗的可以这样理解:
你在处理包含中文或者其他什么编码的字符串的时候,用一个铁则,首先将它解码成unicode,然后对解码后的unicode字符串进行操作;
下面给个例子:
- #-*-coding:utf-8-*-
- import urllib
- import re
- def getchapids(url_m):
- html = urllib.urlopen(url_m).read()
- details = html.decode("gbk").encode("utf-8")
- reg = r'<dd><a href="\/6_6919\/(.*?)\">'
- ids = re.findall(reg,details)
- sd = ids[:9]
- for s in sd:
- ids.remove(s)
- return ids
再一个例子:
- #-*-coding:utf-8-*-
- import urllib
- import re
- def getchapids(url_m):
- html = urllib.urlopen(url_m).read()
- details = html.decode("gbk")
- with open("text.txt","w")as f:
- f.write(details.encode("utf-8"))