解决python读取MySQL中文乱码的问题
前言
项目中经常要读取MySQL数据库,python中的pymysql函数可进行相关读取操作,但其中依然会遇到各种各样的问题,因此且做总结。
字符编码类型及查看
字符编码类型
常见字符编码标准包括:国内标准gbk、国际标准 ISO-8859 、国际统一标准 unicode等。
gbk 包含 gb3212、gb18030 等类型;
ISO-8859 包含 latin1(也称 ISO-8859-1)、latin2 等类型;
unicode 包含 utf-8、utf-16 等类型。
python3中等默认编码类型是utf-8
,如果需要读写其他类型就需要特别声明对应的编码类型。
编码类型查看方法
python中可以通过chardet
查看字符类型。
import chardet
for line in test:
print(chardet.detect(line))
**注意:
- ** 如果报错
TypeError: Expected object of type bytes or bytearray, got: <class 'str'>
,则说明 line 是str格式,需要先转码为相应的字符串格式,例如utf-8等。charset.dectect()
得到的是关于编码类型的0-1的置信度,一般来说达到99%置信度的结果就比较准确了。
因为数据的编码格式分为str和byte两种格式,而 charset
只能用来查看byte类型的数据。
python中的编码和解码
python中字符转码可以通过encode
和decode
实现。
encode
将str转化为byte格式;
decode
将byte转化为str格式。
这样查看编码就可以采用以下方式:
import chardet
for line in test:
lines = line.encode('encoding')
print(chardet.detect(lines))
MySQL中latin1编码数据的读取方式
这个问题困扰了好几天,网上查了不少内容,发现最后还是得通过编码和解码解决。
面对问题
一些老的MySQL库在建表时设置编码方式为默认的latin1类型,这导致存入其中的中文字符在 SELECT
读取数据时会出现乱码。
预期目标
正确读取中文字符并输出。
解决方法
- 在用python读取数据库时设置读取类型
charset='latin1'
:
import pymysql
conn = pymysql.connect(host='host', port='port', user='user_name', passwd='password', db='database', charset='charset')
- 在读取对应表后将中文字符转码存入txt文件:
path = './test.txt'
with open(path, 'w') as f:
for line in title:
lines = line.encode('latin1').decode('gb18030', 'ignore')
f.write(str(lines)+'\n')
这里 decode
中采用的编码类型是gb18030,这是因为 gb18030 是 gbk 的一种扩展类型,包含更多的汉字,同时完全支持 unicode。
此外,decode
中还加入了参数 ignore ,这是因为如果没有忽略特殊字符的说明会出现如下错误,此时会发现能够得到一部分显示正确的数据但不全:
UnicodeDecodeError: 'gb18030' codec can't decode byte 0xba in position 49: incomplete multibyte sequence
OK,这样就解决了读取MySQL数据库中文乱码的问题了。