UnicodeEncodeError错误:字符编码错误
在Python3中,对中文进行了全面的支持,但在Python2.x中中文会出现各种编码问题,处理不当就会出现乱码。
python里的字符默认的编码方式是:
ASCII码,
字母、标点和其他字符只使用一个字节来表示,但对于中文字符来说,一个字节满足不了需求,因此
碰到中文的时候就会乱码。
所以在编写源代码文件
xxx.py
时需要注意:
- 如果源代码没有声明编码格式,则Python在语法校验期间(compilation)使用默认的ASCII编码
- 如果源代码没有声明编码格式,但却在源码中使用了非ASCII字符(Non-ASCII character),则程序在编译期间抛出SyntaxError异常,编译不被通过
- 如果源代码声明了Python不支持的编码格式,则程序将在编译期间抛出异常
采用两个字节的中文编码标准有:GB2312、GBK、BIG5等。
解决办法:告诉Python编译器:脚本中包含了非ASCII字符,并未进行转换
在文件的开头加上
# -*- coding: utf-8 -*-
utf-8是Unix下的一种通用编码,可以对汉字编码
unicode和utf-8本质上是两个东西
- unicode 只是字符集,而不是编码方式
- utf-8 一种编码方式
utf-8是对unicode字符集进行编码的一种编码方式
如何查看自己要爬取的网页的编码方式
直接查看源代码/通过chardet模块来识别
关于Python的编码、乱码以及Unicode的一些研究
首先,在我们编写python代码的时候就要注意一些编码的规范。
1.源码文件用#-*-coding:utf-8-*- 指定编码并把文件保存为utf-8格式
2.文件开头使用from __future__ import unicode_literals 以此避免在中文前面加u,以考虑到迁移到python3。
3.python内部是用Unicode存储的,所有的输入要先decode变成unicode,输出的时候encode变成想要的编码。在window环境下常用到的有utf-8,gbk,gb2312,gb18030等。
4.一般网站基本都是utf-8或者gb2312。可以尝试进行decode,然后encode 当前输出环境的编码格式,系统默认的编码格式通过sys.getfilesystemencoding()。涉及到文件路径的时候要转换为系统默认的编码。
转换系统默认编码的方式:
type = sys.getfilesystemencoding() html = html.decode(
'utf-8'
).encode(type)
5.unicode字符串在写入文件时必须转换为某种字符编码。
python里打印中文汉字的时候需要在字符串前面加 u,这样中文才能正常显示,这里面的u的作用就是将后面的字符串转换为unicode码。
编码和解码
从Unicode类型到GBK或UTF-8等编码的转换,叫做编码(encode);而这一过程的逆过程,则叫做解码(decode)
字符串在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成其他编码。
遇到乱码问题,按上述思路分析一遍,再将乱码所在字符串按它的原始编码decode成Unicode类型的,再使用Unicode类型的编码进行输入、输出即可解决乱码问题。
如果一个字符串已经是unicode了,再进行解码则将出错,因此通常要对其编码方式是否为unicode进行判断:
isinstance(s, unicode) #
用来判断是否为unicode
用非unicode编码形式的str来encode会报错
如果需要将字符串按照指定的字符集保存,有以下几个步骤:
1:用
unicode(str,"原来的编码")
或者
str.decode(
"指定的字符集"
)
将str解码成unicode字符串
2:将unicode字符串str 使用
str.encode("指定的字符集")
转换成你指定的字符集
可以在decode()中加入参数。如:
decode('gb2312', 'ignore')
意思上忽略非gb2312编码的字符,这样就不会报错了。其他类似的参数如下:
默认的参数就是strict,代表遇到非法字符时抛出异常;
如果设置为ignore,则会忽略非法字符;
如果设置为replace,则会用?号取代非法字符;
如果设置为xmlcharrefreplace,则使用XML的字符引用。