使用Python3.4+pymysql无法获取非英文数据,报UnicodeEncodeError
我之前也踩过这个一模一样的坑!Python3.4的编码机制加上pymysql的细节,很容易在读取非英文数据时出问题——尤其是你已经设置了charset='utf8'和use_unicode=True还报错的情况,大概率是终端输出编码或者MySQL字符集的细节没处理好。
先搞清楚报错原因
你遇到的UnicodeEncodeError: 'ascii' codec can't encode characters,本质上不是数据库读取的问题:因为开启了use_unicode=True,pymysql已经把数据转成Python3的Unicode字符串了,问题出在print输出时,系统默认用了ASCII编码去处理Unicode字符串,而Python3.4默认不会自动把stdout的编码改成UTF-8(除非终端本身提前设置)。
具体解决方案
1. 强制设置stdout的编码为UTF-8
在脚本开头加上这段代码,强制让print输出用UTF-8编码,绕开终端默认编码的限制:
# -*- coding: utf-8 -*- import sys import codecs import pymysql # 修复stdout编码问题 if sys.stdout.encoding != 'utf-8': sys.stdout = codecs.getwriter('utf-8')(sys.stdout.buffer, 'strict')
2. 把MySQL连接的charset改成utf8mb4
MySQL的utf8其实是utf8mb3,只支持最多3字节的Unicode字符,不支持emoji或者一些生僻汉字。把连接参数里的charset='utf8'改成charset='utf8mb4',同时确保你的数据库表、字段的字符集也是utf8mb4:
db = pymysql.connect( # 其他参数(host/user/password/database)... charset='utf8mb4', use_unicode=True )
这个改动能彻底避免因为特殊非英文字符导致的编码失败。
3. 验证数据读取是否正常
可以先跳过print,直接检查读取到的字符串类型,确认数据库读取环节没问题:
for row in cur: content = row['content'] print(type(content)) # 正常应该输出 <class 'str'>,也就是Python3的Unicode字符串 # 如果要保存或处理,直接用str类型即可,不要手动转码
补充说明
你脚本开头的# -*- coding: utf-8 -*-只是用来告诉Python解释器脚本文件本身的编码,和运行时的输出编码、数据库读取编码没有关系,所以加了它也解决不了这个问题哦。
内容的提问来源于stack exchange,提问作者com

