我正在尝试将我的Wi-Fi SSID更改为表情符号,但Web UI不允许使用。相反,我捕获了到路由器API的有效PUT请求,使用Chrome的开发工具将其复制为fetch
调用,将SSID更改为表情符号,然后重播请求。效果很好。
但是,当我尝试使用Python Requests进行操作时,它会将表情符号(?
)转义为相应的JavaScript转义:\uD83E\uDD20
。当此消息发送到路由器时,它将以某种方式转换为>
(大于符号,后跟一个空格)。这令人沮丧,因为我假设这两种方法都会以相同的方式编码表情符号。
由于它可以与JavaScript的fetch
配合使用,因此消息或表情符号的编码方式必须有所不同。
提取呼叫:(即使使用开发工具检查请求,表情符号也只是显示为表情符号)(为简洁起见进行了编辑)
fetch("https://192.168.1.1/api/wireless", {
"credentials": "omit",
"headers": {
"accept": "application/json, text/plain, */*",
"content-type": "application/json;charset=UTF-8",
"x-xsrf-token": "[The token for this login session]"
},
"referrer": "https://192.168.1.1/",
"referrerPolicy": "no-referrer-when-downgrade",
"body": "{
\"wifi\": [{
\"boring key 1\": \"boring value\",
\"boring key 2\": \"boring value\",
\"ssid\": \"?\",
\"boring key 3\": \"boring value\",
\"boring key 4\": \"boring value\"
}]
}",
"method": "PUT",
"mode": "cors"
});
请求呼叫:(为简便起见进行编辑)
res = session.put('https://192.168.1.1/api/wireless',
verify=False,
json={
"wifi":[{
"boring key 1":"boring value",
"boring key 2":"boring value",
"ssid":"?",
"boring key 3":
"boring value",
"boring key 4":"boring value"
}]
})
那么编码方式有何不同?我怎么看什么是提取的实际输出? (Dev Tools仅显示表情符号,没有转义序列。)
答案 0 :(得分:1)
json
库中requests
参数完成的默认JSON处理实际上将ensure_ascii
为True,从而提供了这种类型的编码形式。本质上,该put
调用将以以下方式发送到服务器:
PUT / HTTP/1.1
Host: 192.168.1.1
User-Agent: python-requests/2.21.0
Accept-Encoding: gzip, deflate
Accept: */*
Connection: keep-alive
Content-Length: 24
Content-Type: application/json
{"demo": "\ud83e\udd20"}
这不是您想要的。为了执行您想要的操作,您将必须手动编码JSON并显式提供标头,如下所示:
requests.put(
'https://192.168.1.1',
data=json.dumps({"demo": "?"}, ensure_ascii=False).encode('utf8'),
headers={'Content-Type': 'application/json'},
)