python 字符编码处理问题总结
Python中常常遇到这种字符编码问题,尤其在处理网页源代码时(特别是爬虫中):
UnicodeDecodeError: ‘XXX' codec can't decode bytes in position 12-15: illegal multibyte...
以下以汉字'哈'来解释作演示样例解释全部的问题,汉字“哈”的各种编码例如以下:
1 UNICODE(UTF8-16): 0xC854
2 UTF-8: 0xE59388
3 GBK: 0xB9FE
除此之外还有如gb2312, big5等。比如一些含有繁体字的页面。比方www.google.com.hk首页中用的就是big5码,
不知道港台的码农同一时候处理简体字繁体字是不是更郁闷 :)
一直以来。python中的中文编码就是一个大问题,为他他并不能智能识别编码,而实际上其它语言也非常难做到。
在html的header里一般都能够找到字符编码比如:
<meta http-equiv="Content-Type" content="text/html;charset=gb2312"/>
当然这不是我们研究的重点,很多其它的时候是我们得知一个字符串是GBK编码, 而要用print等正确的打印出来却不easy...
首先,在python中提到unicode。一般指的是unicode对象,比如'哈哈'的unicode对象为u'\u54c8\u54c8'
而str是一个字节数组。这个字节数组表示的是对unicode对象编码后(如utf-8、gbk、cp936、GB2312)的存储的格式,这里它
仅是一个字节流。没有其他的含义,假设你想使这个字节流显示的内容有意义,就必须用正确的编码格式,解码显示。
比如:(注意是在windows下)
s = u'哈哈'
s_utf8 = s.encode('utf-8')
pirnt s_utf8
>>> 鍝堝搱
悲剧...
s_utf8这时实际上是'\xe5\x93\x88\xe5\x93\x88'
而以下的代码才干够正常显示:
s_gdb = s.encode('gbk') # s_gdk 这时是'\xb9\xfe\xb9\xfe'
print s_gbk
>>> 哈哈 #正常了
由于print语句它的实现是将要输出的内容传 送了操作系统,操作系统会依据系统的编码对输入的字节流进行编码。这就解释了
utf-8格式的字符串“哈哈”,输出的是“鍝堝搱”,由于 '\xe5\x93\x88\xe5\x93\x88'用GB2312去解释,其显示的出来就
“鍝堝搱”。
这里再强调一下,str记录的是字节数组,仅仅是某种编码的存储格式,至于输出到文件或是打印出来是什么格式。
全然取决其解码的编码将它解码成什么样子。
这里再对print进行一点补充说明:当将一个unicode对象传给print时,在内部会将该unicode对象进行一次转换,
转换成本地默认编码(这仅是个人推測)
str和unicode对象的转换,通过encode和decode实现,详细使用例如以下:再次强调windows下:
s = '哈哈'
print s.decode('gbk').encode('utf-8')
>>> 鍝堝搱
反之亦然,有兴趣能够尝试其它转换
有时当我们遇到把s(gbk字符串)直接编码成utf-8的时候。将抛出异常,可是通过调用例如以下代码:
import sys
reload(sys)
sys.setdefaultencoding('gbk')
后就能够转换成功。为什么呢?
在python中str和unicode在编码和解码过程中。假设将一个str直接编码成还有一种编码,会先把str解码成unicode,
採用默认编码,一般默认编码是anscii,所以在上面演示样例代码中第一次转换的时候会出错。
当设定当前默认编码为'gbk'后,就不会出错了。
至于reload(sys)是由于Python2.5 初始化后会删除 sys.setdefaultencoding 这种方法。我们须要又一次加载。
一般不推荐这样使用。本来reload都是应该避免使用的函数。
对于操作不同文件的编码格式的文件,也会遇到这种问题
建立一个文件test.txt,文件格式用ANSI,内容为:
abc中文
然后用python来读取
# coding=gbk
print open("Test.txt").read()
结果:abc中文
把文件格式改成UTF-8:
结果:abc涓枃,显然。这里须要解码:
# coding=gbk
import codecs
print open("Test.txt").read().decode("utf-8")
结果:abc中文
上面的test.txt我是用Editplus来编辑的。但当我用Windows自带的记事本编辑并存成UTF-8格式时,
执行时报错:
Traceback (most recent call last):
File "ChineseTest.py", line 3, in
print open("Test.txt").read().decode("utf-8")
UnicodeEncodeError: 'gbk' codec can't encode character u'\ufeff' in position 0: illegal multibyte sequence
原来,某些软件,如notepad。在保存一个以UTF-8编码的文件时,
会在文件開始的地方插入三个不可见的字符(0xEF 0xBB 0xBF,即BOM)。
因此我们在读取时须要自己去掉这些字符。python中的codecs module定义了这个常量:
# coding=gbk
import codecs
data = open("Test.txt").read()
if data[:3] == codecs.BOM_UTF8:
data = data[3:]
print data.decode("utf-8")
结果:abc中文
最后,有些时候编码搞对了,可是遇到了非法字符。比方产生字符串的来源错误发生。引入了错误值等,这时再次遇到异常
比如:全角空格往往有多种不同的实现方式。比方\xa3\xa0,或者\xa4\x57,
这些字符。看起来都是全角空格。但它们并非“合法”的全角空格
真正的全角空格是\xa1\xa1,因此在转码的过程中出现了异常。
而之前在处理新浪微博数据时。遇到了非法空格问题导致无法正确解析数据。
解决的方法:
将获取的字符串strTxt做decode时。指明ignore。会忽略非法字符,
当然对于gbk等编码,处理相同问题的方法是类似的
strTest = strTxt.decode('utf-8', 'ignore')
return strTest
默认的參数就是strict,代表遇到非法字符时抛出异常;
假设设置为ignore。则会忽略非法字符;
假设设置为replace。则会用?
号代替非法字符;
假设设置为xmlcharrefreplace,则使用XML的字符引用。
其它的以后遇到再总结.....
python 字符编码处理问题总结的更多相关文章
- python 字符编码练习
通过下面的练习,加深对python字符编码的认识 # \x00 - \xff 256个字符 >>> a = range(256)>>> b = bytes(a) # ...
- Python字符编码讲解
声明:本文参考 Python字符编码详解 在计算机中我们不管用什么语言和程序,最终数据在计算机中的都是字节码(也就是01形式)的形式存在的,如果 计算机直接把字节码显示在屏幕上,很明显一般人看不懂字节 ...
- 深入理解Python字符编码--转
http://blog.51cto.com/9478652/2057896 不论你是有着多年经验的 Python 老司机还是刚入门 Python 不久,你一定遇到过UnicodeEncodeError ...
- 深入理解Python字符编码
不论你是有着多年经验的 Python 老司机还是刚入门 Python 不久,你一定遇到过UnicodeEncodeError.UnicodeDecodeError 错误,每当遇到错误我们就拿着 enc ...
- Python字符编码详解,str,bytes
什么是明文 “明文”是可以是文本,音乐,可以编码成mp3文件.明文可以是图像的,可以编码为gif.png或jpg文件.明文是电影的,可以编码成wmv文件.不一而足. 什么是编码?把明文变成计算机语言 ...
- Python字符编码补充
字符编码: Python字符编码贯穿Python学习的始终,现在应用的是Python2中字符编码的问题是很多的. 这次是要彻底解决Python字符编码的问题!!! 1 字符编码的发展过程: 1 .AS ...
- python --- 字符编码学习小结(二)
距离上一篇的python --- 字符编码学习小结(一)已经过去2年了,2年的时间里,确实也遇到了各种各样的字符编码问题,也能解决,但是每次都是把所有的方法都试一遍,然后终于正常.这种方法显然是不科学 ...
- 转1:Python字符编码详解
Python27字符编码详解 声明 一 字符编码基础 1 抽象字符清单ACR 2 已编码字符集CCS 3 字符编码格式CEF 31 ASCII初创 311 ASCII 312 EASCII 32 MB ...
- 转2:Python字符编码详解
1. 字符编码简介 1.1. ASCII ASCII(American Standard Code for Information Interchange),是一种单字节的编码.计算机世界里一开始只有 ...
- python字符编码(二)
一.什么是字符编码 计算机要想工作必须通电,也就是说‘电’驱使计算机干活,而‘电’的特性,就是高低电压(高低压即二进制数1,低电压即二进制数0),也就是说计算机只认识数字 编程的目的是让计算机干活,而 ...
随机推荐
- MVC之前的那点事儿 ---- 系列文章
MVC之前的那点事儿系列,是笔者在2012年初阅读MVC3源码的时候整理的,主要讲述的是从HTTP请求道进入MVCHandler之前的内容,包括了原创,翻译,转载,整理等各类型文章,当然也参考了博客园 ...
- cocos2d-x 3.2 关闭按钮点击立马销毁自己报错
cocos2d-x 3.2 Button点击事件里调用移除当前层报错 http://www.th7.cn/program/ios/201408/271227.shtml 诡异的错误,点击关闭按钮,居然 ...
- MySQL 性能优化技巧
原文地址:MySQL 性能优化技巧 博客地址:http://www.extlight.com 一.背景 最近公司项目添加新功能,上线后发现有些功能的列表查询时间很久.原因是新功能用到旧功能的接口,而这 ...
- Python——基础数据类型(补充)
1.基础数据类型汇总补充 (1)小数据池: 为了节省空间,数字和字符串有,其他的没有[了解] 数字:-5---256之间的数字共用一个内存地址 #(1)i1 = i2 id(i1) == id ...
- wdlinux重新编译nginx
背景: 由于web站点需要换主机,并且切换环境. 站点需要做反相代理(nginx),主机从美国迁移到香港[考虑到速度问题,为什么不用大陆阿里云ECS服务器?几十个域名备案麻烦,还有阿里云内地没有多ip ...
- 微信web端生成支付二维码
授权获取二维码类: <?php /** * Trade类 * @author xyyphp * @date 2016/10/10 */ abstract class TradeControlle ...
- Idea项目:Failed to create a Maven project ‘…pom.xml’ already exists in VFS 解决
在IDEA里面创建Module,因为项目类型原因删掉,又重新创建一个新的,名字没有变.于是报错: Failed to create a Maven project: '**/***/pom.xml' ...
- Linux下压缩与解压
转自:http://www.mike.org.cn/blog/index.php?load=read&id=218###pp=0 [在解压或压缩的时候,一般还使用-v选项来现实正在处理的文件信 ...
- CEF3中js调用delphi内部方法
2015-01-20修改:以下方法不适合delphi7,在CEF3源码中限制了delphi_14 up,对于被我误导的朋友说声抱歉 在CEF1中JS调用delphi的方法已经贴过:http://www ...
- 关于v9缓存的那点事
当做好以后模块后,由于是模块原型性能不佳,故而可以用缓存方式来提升效率.缓存生成可以是模块的一个方法或者一个函数,phpcms的缓存也可以分为不同的类型,比如file,memcache.如果是file ...