的NodeJS。 处理 字符编码

我在处理字符编码方面遇到困难。 我试图刮下面的url:

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(); 

但那是造成 字符。

我已经testing了此页面上面列出的源代码:

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

它似乎检测为latin1,但事情可能是错的。

字符来自连接:

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

这会将每个chunk转换为默认encodingutf8StringBuffer s中任何无效的UTF-8序列都将丢失,并由replaced代替。

你会想把这个chunk作为Buffer直到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); }); 

如果将User-Agent设置为桌面浏览器的User-Agent ,则HTML中的元标记和响应头中的Content-Typecharset设置为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'); }); 

一个Buffer的默认编码是UTF-8,它是一个可变宽度编码系统。 ASCII范围之后的字符使用多个字节进行编码。 如果您接收到latin1特定的字符(codepoints> 127),那么它们将设置第一个位,UTF-8解码器会将其视为多字节字符,最终导致未映射的代码点(显示为 ) 。

iconv有一个stream媒体解码器,你可以pipe你的响应stream。

 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();