根本原因是mysql连接层未启用utf8mb4编码,需在python连接时显式指定charset='utf8mb4',并确保服务端配置、表结构及排序规则均正确支持4字节utf-8字符。

MySQL连接必须启用utf8mb4编码
Python爬虫写入Emoji时报错 Incorrect string value,根本原因是MySQL默认字符集不支持4字节UTF-8字符。哪怕表和字段已设为utf8mb4,如果连接层没配对,照样失败。
关键不是改表结构,而是确保Python连接MySQL时明确指定编码:
-
charset='utf8mb4'必须传给pymysql.connect()或mysql.connector.connect() - SQLAlchemy用户需在数据库URL末尾加
?charset=utf8mb4,例如:mysql+pymysql://user:pass@host/db?charset=utf8mb4 - 若用
mysqldb(已弃用),需额外设置use_unicode=True和charset='utf8mb4'
表与字段要真正使用utf8mb4 COLLATE
只执行 ALTER TABLE t CONVERT TO CHARACTER SET utf8mb4 不够——它可能仍用 utf8mb4_general_ci,而该排序规则对Emoji支持不稳定。生产环境推荐 utf8mb4_0900_as_cs(MySQL 8.0+)或 utf8mb4_unicode_ci(兼容性更好)。
建表时显式声明更可靠:
CREATE TABLE comments ( id INT PRIMARY KEY, content TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
已有表请用完整语句重置字段级collation:
ALTER TABLE t MODIFY content TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;- 别漏掉
MODIFY后的字段定义全貌,否则可能丢失NOT NULL等约束
Python字符串本身无需encode/decode干预
现代Python 3(3.6+)中,字符串原生是Unicode,爬到的含Emoji文本(如"Hello ?")直接传给SQL执行即可。常见错误是手动调用 .encode('utf8') 再解码,反而引入乱码或截断。
快速生成专业的 Python 脚本和应用代码。一键创建完整项目结构,支持CLI、API、爬虫、Bot、Django等多种项目类型,包含完整的项目结构、配置文件、依赖管理、测试、README和文档。
只需确认两点:
- 源网页响应头或meta声明的编码被requests正确识别(可用
r.apparent_encoding验证) - 解析HTML时用
BeautifulSoup(html, 'html.parser', from_encoding='utf-8')显式指定,避免BS自动猜错 - 若原始数据来自JSON API,
json.loads()默认处理Unicode,无需额外操作
检查MySQL服务端配置是否生效
即使应用层全配对,MySQL服务端若没开utf8mb4支持,连接时仍会降级。登录MySQL执行:
SHOW VARIABLES LIKE 'character_set%';<br>SHOW VARIABLES LIKE 'collation%';
重点看这几项必须是utf8mb4:
character_set_clientcharacter_set_connectioncharacter_set_databasecharacter_set_server
若不是,需修改my.cnf并重启:
[client]<br>default-character-set = utf8mb4<br><br>[mysql]<br>default-character-set = utf8mb4<br><br>[mysqld]<br>character-set-server = utf8mb4<br>collation-server = utf8mb4_unicode_ci
注意:MySQL 5.7之前版本的max_allowed_packet过小也可能导致Emoji写入中断,建议至少设为64M
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










