使用请求 restful 客户端时出现阿拉伯语编码错误
Arabic encoding error when using requests restful client
我在 python 中有以下 restful 客户端:
import requests;
s= 'وإليك ما يقوله إثنان من هؤلاء';
resp = requests.post('http://localhost:8080/MyApp/webresources/production/sendSentence', json={'sentence': s,} )
上述代码调用 java 中实现的 Web 服务,其中 returns 从请求客户端发送相同的语句。
这是 java 网络服务:
@POST
@Consumes("application/json")
@Produces("text/html; charset=UTF-8")
@Path("/sendSentence")
public String sendSentence(@Context HttpServletRequest requestContext, String valentryJson) throws Exception {
try {
if (valentryJson != null) {
JSONObject jsonObject;
jsonObject = new JSONObject(valentryJson);
String sentence = jsonObject.getString("sentence");
return sentence;
}
} catch (JSONException ex) {
}
return "";
}
问题出在编码上,因为当我尝试打印内容时,结果是这样的:
>>> resp.content
'\xd9\x88\xd8\xa5\xd9\x84\xd9\x8a\xd9\x83 \xd9\x85\xd8\xa7 \xd9\x8a\xd9\x82\xd9\x88\xd9\x84\xd9\x87 \xd8\xa5\xd8\xab\xd9\x86\xd8\xa7\xd9\x86 \xd9\x85\xd9\x86 \xd9\x87\xd8\xa4\xd9\x84\xd8\xa7\xd8\xa1'
或者当我使用打印时:
>>> print resp.content
ظˆط¥ظ„ظٹظƒ ظ…ط§ ظٹظ‚ظˆظ„ظ‡ ط¥ط«ظ†ط§ظ† ظ…ظ† ظ‡ط¤ظ„ط§ط،
您的 Java 网络服务生成 HTML,UTF-8 编码:
@Produces("text/html; charset=UTF-8")
但是你在没有解码的情况下获取了返回的原始字节:
>>> resp.content
response.content
为您提供字节,而不是 Unicode 文本。您可以改用 resp.text
属性,它使用 Content-Type
header 的 charset
参数来解码您的数据:
>>> resp.text
u'\u0648\u0625\u0644\u064a\u0643 \u0645\u0627 \u064a\u0642\u0648\u0644\u0647 \u0625\u062b\u0646\u0627\u0646 \u0645\u0646 \u0647\u0624\u0644\u0627\u0621'
>>> print resp.text
وإليك ما يقوله إثنان من هؤلاء
但是要小心;如果存在 no charset
参数,但 content-type header 表示这是 text/...
内容类型(如 text/html
),那么 requests
将遵循 HTTP RFC 并将数据解码为 Latin-1。这将默默地工作,但可能不是正确的编解码器。对于 HTML 数据,请改用 HTML 解析器,传入字节串,并将其留给解析器来提取正确的编解码器(HTML 通常将正确的编码记录在 <meta>
标签)。参见 retrieve links from web page using python and BeautifulSoup。
我在 python 中有以下 restful 客户端:
import requests;
s= 'وإليك ما يقوله إثنان من هؤلاء';
resp = requests.post('http://localhost:8080/MyApp/webresources/production/sendSentence', json={'sentence': s,} )
上述代码调用 java 中实现的 Web 服务,其中 returns 从请求客户端发送相同的语句。
这是 java 网络服务:
@POST
@Consumes("application/json")
@Produces("text/html; charset=UTF-8")
@Path("/sendSentence")
public String sendSentence(@Context HttpServletRequest requestContext, String valentryJson) throws Exception {
try {
if (valentryJson != null) {
JSONObject jsonObject;
jsonObject = new JSONObject(valentryJson);
String sentence = jsonObject.getString("sentence");
return sentence;
}
} catch (JSONException ex) {
}
return "";
}
问题出在编码上,因为当我尝试打印内容时,结果是这样的:
>>> resp.content
'\xd9\x88\xd8\xa5\xd9\x84\xd9\x8a\xd9\x83 \xd9\x85\xd8\xa7 \xd9\x8a\xd9\x82\xd9\x88\xd9\x84\xd9\x87 \xd8\xa5\xd8\xab\xd9\x86\xd8\xa7\xd9\x86 \xd9\x85\xd9\x86 \xd9\x87\xd8\xa4\xd9\x84\xd8\xa7\xd8\xa1'
或者当我使用打印时:
>>> print resp.content
ظˆط¥ظ„ظٹظƒ ظ…ط§ ظٹظ‚ظˆظ„ظ‡ ط¥ط«ظ†ط§ظ† ظ…ظ† ظ‡ط¤ظ„ط§ط،
您的 Java 网络服务生成 HTML,UTF-8 编码:
@Produces("text/html; charset=UTF-8")
但是你在没有解码的情况下获取了返回的原始字节:
>>> resp.content
response.content
为您提供字节,而不是 Unicode 文本。您可以改用 resp.text
属性,它使用 Content-Type
header 的 charset
参数来解码您的数据:
>>> resp.text
u'\u0648\u0625\u0644\u064a\u0643 \u0645\u0627 \u064a\u0642\u0648\u0644\u0647 \u0625\u062b\u0646\u0627\u0646 \u0645\u0646 \u0647\u0624\u0644\u0627\u0621'
>>> print resp.text
وإليك ما يقوله إثنان من هؤلاء
但是要小心;如果存在 no charset
参数,但 content-type header 表示这是 text/...
内容类型(如 text/html
),那么 requests
将遵循 HTTP RFC 并将数据解码为 Latin-1。这将默默地工作,但可能不是正确的编解码器。对于 HTML 数据,请改用 HTML 解析器,传入字节串,并将其留给解析器来提取正确的编解码器(HTML 通常将正确的编码记录在 <meta>
标签)。参见 retrieve links from web page using python and BeautifulSoup。