Python 的编码问题

我在爬取网页解析的过程中出现了网页内容解析不了的问题,虽然用记事本打开是显示正常的汉字和符号,但用winhex打开就会出现乱码的问题(把它放到cmd中也显示乱码),这个一般就是编码问题,这种 编码应该很可能是 utf-8 ,能在winhex中正常显示汉字的应该是GB2312或者GBK编码,所以用正则表达式匹配感觉没问题,其实匹配不到,所以一般就需要将其转化为GBK或者GB2312格式

那么,怎么才能知道文件内容或字符串是什么编码方式,python提供了chardet的模块,它直接可能帮我们检测其编码格式。

使用 chardet 可以很方便的实现字符串/文件的编码检测。尤其是中文网页,有的页面使用GBK/GB2312,有的使用UTF8,如果你需要去爬一些页面,知道网页编码很重要的,虽然HTML页面有charset标签,但是有些时候是不对的。那么chardet就能帮我们大忙了。

一下就是使用方式

 import urllib
 rawdata = urllib.urlopen('http://www.google.cn/').read()
import chardet
 chardet.detect(rawdata)
{'confidence': 0.98999999999999999, 'encoding': 'GB2312'}

所以这样我们就知道其编码方式是什么了,这样也很方便!


那么python又应该如何转码呢?

这里又提供了两个主要的转码函数:

字符串在Python内部的表示是unicode编码,因此,在做编码转换时,通常需要以unicode作为中间编码,即先将其他编码的字符串解码(decode)成unicode,再从unicode编码(encode)成另一种编码。

decode的作用是将其他编码的字符串转换成unicode编码,如str1.decode('gb2312'),表示将gb2312编码的字符串str1转换成unicode编码。

encode的作用是将unicode编码转换成其他编码的字符串,如str2.encode('gb2312'),表示将unicode编码的字符串str2转换成gb2312编码。

因此,转码的时候一定要先搞明白,字符串str是什么编码,然后decode成unicode,然后再encode成其他编码

使用方法:s=s.decode('gb2312').encode('utf-8') 如此而已


中文的unicode形如:\u34e3 这样,那应该如何转化为正常的汉字呢?

>>> r=u'5f37'
>>> print r
5f37
>>> r1=unichr(int(r,16))
>>> print r1

还有一个unicode转换汉字的方法:

>>> s1='\u4e2d\u56fd'
>>> str=s1.decode('unicode_escape')
>>> print str
中国

*还有的情况就是文本中会有中文的符号python会检测到不认识,如“;”所以我们需要更改系统默认编码和将含有中文字符的文本字符转化为gbk编码:a.decode('utf-8').encode('gbk')假使原先为utf-8编码,然后再进行下面转化:以下有几种方法:

python在安装时,默认的编码是ascii,当程序中出现非ascii编码时,python的处理常常会报这样的错UnicodeDecodeError: 'ascii' codec can't decode byte 0x?? in position 1: ordinal not in range(128),python没办法处理非ascii编码的,此时需要自己设置将python的默认编码,一般设置为utf8的编码格式。

查询系统默认编码可以在解释器中输入以下命令:

Python代码     
  1. >>>sys.getdefaultencoding()  

设置默认编码时使用:

Python代码     
  1. >>>sys.setdefaultencoding('utf8')  

 可能会报AttributeError: 'module' object has no attribute 'setdefaultencoding'的错误,执行reload(sys),在执行以上命令就可以顺利通过。

此时在执行sys.getdefaultencoding()就会发现编码已经被设置为utf8的了,但是在解释器里修改的编码只能保证当次有效,在重启解释器后,会发现,编码又被重置为默认的ascii了,那么有没有办法一次性修改程序或系统的默认编码呢。

 

有2种方法设置python的默认编码:

一个解决的方案在程序中加入以下代码:

Python代码     
  1. import sys  
  2. reload(sys)  
  3. sys.setdefaultencoding('utf8')   

 另一个方案是在python的Lib\site-packages文件夹下新建一个sitecustomize.py,内容为:

Python代码     
  1. # encoding=utf8  
  2. import sys  
  3.   
  4. reload(sys)  
  5. sys.setdefaultencoding('utf8')   

此时重启python解释器,执行sys.getdefaultencoding(),发现编码已经被设置为utf8的了,多次重启之后,效果相同,这是因为系统在python启动的时候,自行调用该文件,设置系统的默认编码,而不需要每次都手动的加上解决代码,属于一劳永逸的解决方法。

 

另外有一种解决方案是在程序中所有涉及到编码的地方,强制编码为utf8,即添加代码encode("utf8"),这种方法并不推荐使用,因为一旦少写一个地方,将会导致大量的错误报告,我曾经遇到这种情况,错误日志压缩之后尚有70多K,全都是这一个问题,让人有很崩溃的感觉。



+++++++++++++++++++++++++++++++++++++++

最近又遇到的问题是读文件是utf-8或者ascii编码文件,它不能encode成gbk,但是我想判断 ‘今天’  这两个字是否在文件字符串里,所以直接用

if "今天" in post_time: 是有问题的

想要解决这个问题的方法是:

if "今天".decode('gbk').encode('utf-8') in post_time:  通过把汉字转换成utf-8 即可


+++++++++++++++++++++++++++++++++++++++++++

para_pattern=re.compile(r'<strong class=\"\">(\d+)<\/strong><span>[\x80-\xff]{3}[\x80-\xff]{3}',re.S)'


匹配汉字,且字符串编码为utf-8,如果匹配正常汉字有问题的就可以采用这种办法,匹配其中的汉字可以用这种方法,一个字是用三个字节表示的










  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值