天天看點

python讀取MySQL的一些問題(二):解決python讀取MySQL中文亂碼的問題前言字元編碼類型及檢視python中的編碼和解碼MySQL中latin1編碼資料的讀取方式

解决python读取MySQL中文乱码的问题

  • 前言
  • 字符编码类型及查看
      • 字符编码类型
      • 编码类型查看方法
  • python中的编码和解码
  • MySQL中latin1编码数据的读取方式
      • 面对问题
      • 预期目标
      • 解决方法

前言

项目中经常要读取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))
           
**注意:
  1. ** 如果报错

    TypeError: Expected object of type bytes or bytearray, got: <class 'str'>

    ,则说明 line 是str格式,需要先转码为相应的字符串格式,例如utf-8等。
  2. 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

读取数据时会出现乱码。

预期目标

正确读取中文字符并输出。

解决方法

  1. 在用python读取数据库时设置读取类型

    charset='latin1'

    :
import pymysql
conn = pymysql.connect(host='host', port='port', user='user_name', passwd='password', db='database', charset='charset')
           
  1. 在读取对应表后将中文字符转码存入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数据库中文乱码的问题了。