Java和Python之间的多字节字符(UnicodeEncodeError)

时间:2014-05-02 20:56:34

标签: java python unicode multibyte

我目前正在开发一个调用Java REST API并检索多语言结果的Django应用程序(结果来自Elasticsearch开始)。我可以检索结果并将它们存储到一个对象中,但是在Javascript中显示它们会给我垃圾 - 这应该是俄语:

a junk

将其转换为字符串或尝试转换为unicode时,我得到:

UnicodeEncodeError at /getObjectArticles
'ascii' codec can't encode characters in position 23-24: ordinal not in range(128)

我知道API正在返回良好的数据,因为使用Java应用程序调用工作正常。知道如何处理传入的字符串,这将是可识别的字符吗?

编辑:我的摄取代码..

g = requests.post(baseUrl, query_string)

except requests.exceptions.RequestException as e:
    print e

try:
    obj = g.json()
    articleTitle = obj['hit']['title']
    str(articleTitle)   # This results in a Unicode error
    articleTitle.decode("UTF-8")   # This results in a Unicode error

编辑:我的Javascript / JQUERY

// Load article text
function getArticleText(articleId, index) {
    console.log($('#result_number').val());
    var es_url = gu.webapp_url + '/getArticle?articleId=' + encodeURIComponent(articleId) + "&index=" + encodeURIComponent(index);

    $.get(es_url).success(function(data) {
        console.log(data);
        var decodedText = $("<div/>").html(data.text).text();
        var decodedTitle = $("<div/>").html(data.articleTitle).text();

        // Close Article View Button
        $('#g2i2-article-info').html("<div id=\"closeArticleInfo\" class=\"closeWindow\">X</div>");

        // Article Info Table
        var articleTable = "<table class=\"table table-striped table-bordered table-condensed\">";
        articleTable = articleTable + "<tr><td>Title</td><td>" + decodedTitle + "</td></tr>";
        articleTable = articleTable + "<tr><td>Publication Date</td><td>" + data.pubDate + "</td></tr>";
        articleTable = articleTable + "<tr><td>Source Name</td><td>" + data.sourceName + "</td></tr>";
        articleTable = articleTable + "<tr><td>Location</td><td>" + data.locationName + "</td></tr>";
        articleTable = articleTable + "<tr><td>URL</td><td>" + data.url + "</td></tr>";
        articleTable = articleTable + "</table>"
        $('#g2i2-article-info').append(articleTable);

        // Article Text
        $('#g2i2-article-info').append(decodedText);
        $('#g2i2-article-info').css('display', 'block');

    }).error(function(jqXHR, textStatus, errorThrown) {
        console.log(textStatus + " " + errorThrown);
    });

}

1 个答案:

答案 0 :(得分:1)

您的服务器上已有Unicode数据; response.json()为任何JSON字符串生成Unicode值。没有必要尝试解码它。

正在生成此Latin 1 Mojibake浏览器。浏览器发送UTF-8(多字节编码),浏览器将单个字节解释为拉丁文1个字符。例如,您的标题以Cyrilic文本Со开头,该文本编码为UTF-8,然后被误解为拉丁文1:

>>> u'Со'
u'\u0421\u043e'
>>> u'Со'.encode('utf8')
'\xd0\xa1\xd0\xbe'
>>> print u'Со'.encode('utf8').decode('latin1')
Со

因此,UTF-8中的D0 A1字节构成了一个代码点,而是打印为两个Latin-1字符。

Ñ字符是D1字节,后面可以跟着大约33个不可打印的第二个UTF-8字节,以便在р到{{范围内创建一个字符1}}。接下来是Ѡ,它实际上是и等等。

您需要弄清楚为什么浏览器认为您的数据是拉丁文1。

通常这是从发送到浏览器的и标头确定的;如果它设置为Content-Type,则浏览器的行为就像所有文本都是拉丁文1.可能是HTML页面有text/html; charset=ISO-8851-1标记,<meta>或{{1}之一或类似的,其中有几个密切相关的编码都具有相似的Mojibake效应。

另一种选择是你明确地将它编码为UTF-8,然后在将它发送到浏览器之前再次将其解码到Latin-1。

第三个选项是您使用的JSON服务本身在JSON unicode字符串中发送了Latin-1字节,为您提供了Mojibake源代码。在这种情况下,您仍然可以通过编码为Latin 1然后从UTF-8解码来修复它:

<meta charset="ISO-8851-1">

但只有在您确认服务器上的数据已经是Mojibaked之后才会这样做。