如何阻止Python requests.post将字符串编码为UTF-8?
问题分析与解决方案
问题核心
使用requests.post的json=参数时,内部默认调用Python标准库的json.dumps且开启ensure_ascii=True,导致所有非ASCII字符被自动转义为\uXXXX格式的Unicode序列(比如é变成\u00e9),但设备要求直接发送原始带重音字符的JSON文本,因此出现解析异常。而curl是直接发送原始字符串未做转义,所以能正常工作。
解决方案
不需要重写HTTP POST逻辑,只需手动控制JSON序列化和编码过程,绕过requests默认的转义行为:
方法1:手动序列化JSON并指定编码
使用json.dumps时设置ensure_ascii=False生成保留原始字符的JSON字符串,再编码为设备兼容的编码(比如ISO-8859-1/Latin-1,这是curl默认发送单字节重音字符的常用编码),最后通过data=参数发送,同时指定正确的Content-Type头。
示例代码:
import requests import json payload = { "type": "send-message", "username": "myuser", "password": "mypass", "to": "456", "msg": "here are accents: é ç" } # 生成不转义非ASCII字符的JSON字符串 json_str = json.dumps(payload, ensure_ascii=False) # 编码为ISO-8859-1(匹配设备期望的单字节编码) encoded_data = json_str.encode('ISO-8859-1') # 发送请求,指定Content-Type包含对应字符集 headers = {'Content-Type': 'application/json; charset=ISO-8859-1'} resp = requests.post("http://192.168.1.10/send_message.html", data=encoded_data, headers=headers)
方法2:直接构造JSON字符串(不推荐,易出错)
如果payload结构简单,也可以直接编写JSON字符串再编码发送:
import requests json_str = '{"type": "send-message","username": "myuser","password": "mypass","to": "456","msg": "here are accents: é ç" }' encoded_data = json_str.encode('ISO-8859-1') headers = {'Content-Type': 'application/json; charset=ISO-8859-1'} resp = requests.post("http://192.168.1.10/send_message.html", data=encoded_data, headers=headers)
关键说明
ensure_ascii=False是核心配置:让json.dumps保留原始非ASCII字符,不转义为Unicode序列。- 编码选择:如果设备实际兼容UTF-8,也可以替换为
utf-8编码,但需保证Content-Type的charset与编码一致。从curl的正常表现来看,设备接受单字节编码的原始字符,因此ISO-8859-1是更匹配的选择。
内容的提问来源于stack exchange,提问作者Love2Code
相关产品推荐
相关产品推荐

