今天使用python爬数据的时候遇到了类似如下的报错:UnicodeEncodeError: 'ascii' codec can't encode character u'\xe0' in position 4: ordinal not in range(128),便上网查一查资料,发现原来是unicode编码的问题,也不只一次遇见过这样的问题,便想把它记录下来,以便日后翻看。在Stack Overflow上找到类似的案例,也提供了解决方案。
总结一下:
用通信理论的思路可以理解为:
unicode是信源编码,对字符集数字化;
utf8是信道编码,为更好的存储和传输。
一句话说:UTF-8 是一种 Unicode 字符集的编码方式。
一,通过例子理解字符编码
在Python中有两个和字符很相关的类型,一个是str类型,一个是unicode类型。
这两种类型的对象都是sequece序列,其中str是字节序列,而unicode是字符序列 。
在2.x版本的python中,默认定义的字符串是str类型的,而在python3k中,所有的str类型的字符串默认就是unicode字符串。
二.Python中和编码相关的两个函数
在Python中和编码相关的两个函数为decode和encode,其中encode()是将某个unicode字符串按照一定的编码方式编码成字节序列而decode()是一个反过程,将一个字节序列按照一定的编码方式解码成unicode字符串。
那么python这么实现主要是为了方便当某个对象不确定是str还是unicode类型的时候,用encode函数总是不会出现错误。
那么问题来了,为什么会出现'ascii'这个编码呢?原因是python在安装时,默认的编码是ascii,当程序中出现非ascii编码时,python的处理常常会报这样的错,python没办法处理非ascii编码的,此时需要自己设置将python的默认编码,一般设置为utf8的编码格式。查阅网上,可以在程序中修改所有涉及到编码的地方,强制编码为utf8,即添加代encode("utf8"),这种方法并不推荐使用,因为一旦少写一个地方,将会导致大量的错误报告。
这里介绍一个一次性修改后永久生效的方法:
更改 sys.defaultencoding 为文件的编码方式
#! /usr/bin/env python
# -*- coding: utf-8 -*-
import sys
reload(sys) # Python2.5 初始化后会删除 sys.setdefaultencoding 这个方法,我们需要重新载入
sys.setdefaultencoding('utf-8')