的NodeJS。处理 字符编码

时间:2014-10-27 02:21:13

标签: node.js character-encoding

我在处理字符编码方面遇到了困难。我正试图抓取以下网址:

http://www.google.com/movies?near=Montreal&date=0

我的代码如下所示:

var http = require('http');
var url = require('url');
var Iconv  = require('iconv').Iconv;

var location = 'montreal';

var googleMovies = url.parse("http://www.google.com/movies?near=" + location);

var req = http.request(googleMovies, function(response) {
    var str = '';
    response.on('data', function(chunk) {
        str += chunk;
    });
    response.on('end', function() {

        var iconv = new Iconv('latin1', 'UTF-8');
        str = iconv.convert(str).toString();

        console.log(str);
    });
});
req.end()

我第一次尝试没有:

    var iconv = new Iconv('latin1', 'UTF-8');
    str = iconv.convert(str).toString();

但这导致了 角色。

我已在此页面上测试了上面列出的来源:

http://nlp.fi.muni.cz/projects/chared/

并且它似乎将其视为latin1,但事情可能是错误的。

3 个答案:

答案 0 :(得分:7)

�字符来自串联:

response.on('data', function(chunk) {
    str += chunk;
});

这会使用default encoding of utf8将每个chunk转换为StringBuffer中任何无效的UTF-8序列都会丢失,并在此时被�取代。

您希望将chunk作为Buffer s,直到convert()之后。它们可以在Array中收集,并与Buffer.concat()结合使用。

var chunks = [];

response.on('data', function (chunk) {
    chunks.push(chunk);
});

response.on('end', function () {
    var iconv = new Iconv('latin1', 'UTF-8');
    var str = iconv.convert(Buffer.concat(chunks)).toString();
    console.log(str);
});

答案 1 :(得分:2)

如果您将User-Agent设置为桌面浏览器,则HTML中的元标记和响应标头中的Content-Type会将charset设置为UTF-8 latin1。例如:

var dest = url.parse('http://www.google.com/movies?near=montreal');
dest.headers = {
  'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.104 Safari/537.36',
};

http.get(dest, function(response) {
  var str = '';

  response.on('data', function(chunk) {
    str += chunk;
  }).on('end', function() {
    console.log(str);
  }).setEncoding('utf8');
});

答案 2 :(得分:1)

Buffer的默认编码是UTF-8,它是一种可变宽度编码系统。 ASCII范围后的字符使用多个字节进行编码。如果您正在接收特定于latin1的字符(代码点> 127),则它们将具有第一个位集,UTF-8解码器将其视为多字节字符,最终导致未映射的代码点(显示为�)。

iconv有一个流式解码器,您可以将响应流传输到。

http.request(googleMovies, function (response) {
    var iconv = new Iconv('latin1', 'UTF-8');
    response.pipe(iconv).pipe(process.stdout);
    //or response.pipe(iconv).on('data', console.log);
}).end();