You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python2 Requests的json参数中设置UTF-8编码处理中文?

解决Python2中requests使用json参数发送中文到BigIP的PATCH请求问题

核心问题原因

在Python2环境下,requests库处理json参数时,默认调用json.dumps()且启用ensure_ascii=True,会将所有非ASCII字符(比如中文)转换为\uXXXX格式的Unicode转义序列。而BigIP的API可能无法正确解析这种转义后的JSON格式,导致返回400错误("double quotes are not balanced")。

此外,如果你提前将Unicode字符串编码为UTF-8字节串再传入json参数,json.dumps()会把字节串中的非ASCII字节再次转义,生成双重转义的JSON,进一步触发解析错误。

解决方案

方案1:猴子补丁修改requests的JSON序列化逻辑(适配固定使用json参数的场景)

如果底层代码固定要求使用json参数,无法直接切换到data参数,可以通过猴子补丁修改requests的请求体处理逻辑,强制使用ensure_ascii=False进行JSON序列化:

import requests
import json

# 替换原有的prepare_body方法
original_prepare_body = requests.models.Request.prepare_body

def patched_prepare_body(self, data, files, json=None):
    if json is not None:
        # 手动序列化JSON,禁用ASCII转义
        import complexjson
        body = complexjson.dumps(json, ensure_ascii=False)
        if not isinstance(body, bytes):
            body = body.encode('utf-8')
        # 调用原方法,传入处理好的字节体
        return original_prepare_body(self, body, files, json=None)
    return original_prepare_body(self, data, files, json)

requests.models.Request.prepare_body = patched_prepare_body

# 原有业务代码(注意不要提前encode中文)
# -*- coding: utf-8 -*-
import base64

url = "https://10.13.7.17/mgmt/tm/ltm/virtual/~Project_6fd06a50b7824ae48386565786e94b38~test"
test2 = u"bu退"
# 直接传递Unicode字符串,无需提前编码
data = {"description": test2}

headers = {
  'Authorization': 'Basic YWRamdflk6YWRtaW5Aasdlfjkla',
}

response = requests.request("PATCH", url, headers=headers, json=data, verify=False)
print(response.text)

方案2:手动序列化JSON并使用data参数(推荐,若允许修改参数类型)

如果可以修改请求参数类型,直接手动控制JSON序列化过程,生成UTF-8编码的原始JSON字节,通过data参数发送:

# -*- coding: utf-8 -*-
import requests
import json
import base64

url = "https://10.13.7.17/mgmt/tm/ltm/virtual/~Project_6fd06a50b7824ae48386565786e94b38~test"
test2 = u"bu退"
data = {"description": test2}

# 手动序列化,禁用ASCII转义并编码为UTF-8字节
payload = json.dumps(data, ensure_ascii=False).encode('utf-8')

headers = {
  'Authorization': 'Basic YWRamdflk6YWRtaW5Aasdlfjkla',
  'Content-Type': 'application/json'  # 必须指定内容类型
}

response = requests.request("PATCH", url, headers=headers, data=payload, verify=False)
print(response.text)

验证逻辑

在Python2中,不同序列化方式的结果对比:

# 原始数据(Unicode字符串)
data = {"description": u"bu退"}

# 默认序列化:转义非ASCII字符
json.dumps(data)
# 输出: '{"description": "bu\\u9000"}'

# 禁用ASCII转义:保留原始字符
json.dumps(data, ensure_ascii=False)
# 输出: u'{"description": "bu\u9000"}'

# 编码为UTF-8字节:适合直接发送给服务器
json.dumps(data, ensure_ascii=False).encode('utf-8')
# 输出: '{"description": "bu\xe9\x80\x80"}'

方案1和方案2最终都会生成最后一种格式的请求体,符合BigIP API的解析要求。

内容的提问来源于stack exchange,提问作者Pzhang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 02:06:04