Linux培训
达内IT学院

400-996-5531

python 中文乱码问题

  • 发布:Linux培训
  • 来源:网络
  • 时间:2015-07-09 11:00

本文主要说明如何从网站获取页面,并且如何查找页面中的中文字符。实验中的平台为python 2.7 。

python2.7 太直接了,操作系统给它什么格式编码的字符串,它就接收啥格式的字符串,默认的格式与你使用的格式不同,因此,各种错误出现了。

解决方法:

1.知道系统所使用的编码格式

2.把获取的页面先用系统格式解码,然后在编码为utf8格式

3.你的脚本中统一使用uft8编码

4.处理结束,把你的字符串先utf8解码,然后系统格式编码。

流程结束

# -*- coding: utf-8 -*-

import sys  

import urllib2    

# 获得系统默认编码格式

sysCharType = sys.getfilesystemencoding()  

# 获取页面

headers = {'User-Agent':'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6'}    

req = urllib2.Request("http://www.baidu.com/", headers=headers)    

html = urllib2.urlopen(req).read()  

sysHtml = html.decode(sysCharType).encode('utf-8')  

s  = '百度一下,你就知道'

if html.find(s)!= -1:  

print'未经转化 字符匹配'

else:  

print'未经转化 字符不匹配'

if sysHtml.find(s)!= -1:  

print'经过转化 字符匹配'

else:  

print'经过转化 字符不匹配'

另,看了kiki113的文章后,大有收获。kiki113的原始帖子地址。

str为字节数组,它仅仅是一个字节流,没有其它的含义。而unicode是一种编码格式。我们可以把具有unicode编码格式的字符串看做字节流,但是不能把随意一个字节流当做unicode字符串解释。这就是在进行字符编码转化中经常发生问题的直接原因。

'您好'的几种编码编码方式结果

GBK\xc4\xfa\xba\xc3

unicode \u60a8\u597d

UTF-8\xe6\x82\xa8\xe5\xa5\xbd

在 python中,如果将一个str直接编码成另一种编码例如UTF-8,则系统先把str解码成unicode,然后把unicode编码格式转化为目标格式(UTF-8),而从str到unicode过程中,系统认为str为默认编码格式,一般认为是ASCII,如果原始编码不是ASCII则会发生错误。

下面来看几个例子

1.查看默认编码格式

>> import sys  

>>> sys.getdefaultencoding()  

'ascii'

>>> s = '您好'

>>> s  

'\xc4\xfa\xba\xc3'#这是GBK编码格式的字节流

>>> s1=u'您好'

>>> s1  

u'\xc4\xfa\xba\xc3'# 这个吗,看看对象类型。u的意义是声明它后面跟随的字符串是unicode格式编码,如果不是,则会出错。

<type 'str'>  

>>> type(s1)  

<type 'unicode'> #s1是unicode类型的,但是里面的内容是GBK格式的

转化到utf-8格式

>>> su = s.encode('utf-8')  

Traceback (most recent call last):  

 File "<pyshell#9>", line 1, in <module>  

   su = s.encode('utf-8')  

UnicodeDecodeError: 'ascii' codec can't decode byte 0xc4in position 0: ordinal notin range(128)  

直接转化发生错误  

>>> su = s.decode('gbk').encode('utf-8')  

>>> su  

'\xe6\x82\xa8\xe5\xa5\xbd'

>>> print su  

鎮ㄥソ  

>>> sun = su.decode('utf-8')  

>>> sun  

u'\u60a8\u597d'

>>> print sun  

您好  

>>> s.decode('gbk')  

u'\u60a8\u597d'

<span>s1.decode('gbk')</span>  

Traceback (most recent call last): File "<pyshell#17>", line 1, in <module> s1.decode('gbk')UnicodeEncodeError: 'ascii'

文件的编码格式和编码声明的作用 把'您好'分别保存为 ASCII格式文件,unicode格式文件,和UTF-8格式文件,使用16进制文件查看其查看文件内容。

可见,采用不同的编码格式,看起来一样的字符,其存储格式是不同的。编码声明就是显式的说明文件中的字符编码格式,并且告知系统,后面遇到的字符,全按照声明的格式去解释。例如脚本文件

[python]view plaincopys = '您好'

print repr(s)

a.如果文件格式为utf-8,则str的值为:'\xe6\x82\xa8\xe5\xa5\xbd'

b.如果文件格式为ASCII,则str的值为:'\xc4\xfa\xba\xc3'

如果编码格式和声明不相符合呢?

文件为UTF-8格式保存,声明为GBK

[python]view plaincopy# -*- coding: GBK -*-

s = '您好'

print repr(s)

print s

运行结果

[python]view plaincopy'\xe6\x82\xa8\xe5\xa5\xbd'

鎮ㄥソ

文件为ASCII,声明为UTF-8(我们知道文件会被保存为GBK格式)

[python]view plaincopy'\xc4\xfa\xba\xc3'

您好

根据上面的讨论,这个好像是理所当然的。来点神奇的。

文件为UTF-8格式保存,声明为GBK

[python]view plaincopy# -*- coding: GBK -*-

s = u'您好'

print repr(s)

print s

运行结果为

[python]view plaincopyu'\u93ae\u3125\u30bd'

鎮ㄥソ

为什么会这样?在运行ss = u'您好'的时候,整个过程可分为以下几步:

1) 获取'您好'的编码:由文件编码格式确定,为‘\xe6\x82\xa8\xe5\xa5\xbd’

2) 转成unicode编码的时候,根据文件的显示编码格式声明对'\xe6\x82\xa8\xe5\xa5\xbd'解码,不是用utf-8解码,而是用声明编码处指定的编码GBK解码,得到字符串‘鎮ㄥソ’',这三个字的unicode编码就是u'/u93ae/u3125/u30bd',因此 print repr(ss)输出的是/u93ae/u3125/u30bd。

预约申请免费试听课

填写下面表单即可预约申请免费试听! 怕学不会?助教全程陪读,随时解惑!担心就业?一地学习,可全国推荐就业!

上一篇:python基础知识总结
下一篇:Python实现十六进制与十进制

关于 python 中的 setup.py

Python 程序员的 10 个常见错误

使用 Python 创建你自己的 Shell (上)

2015年出现的十大流行 Python 库

Copyright © 2023 Tedu.cn All Rights Reserved 京ICP备08000853号-56 京公网安备 11010802029508号 达内时代科技集团有限公司 版权所有

选择城市和中心
黑龙江省

吉林省

河北省

湖南省

贵州省

云南省

广西省

海南省