的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
转换为默认encoding
为utf8
的String
。 Buffer
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-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'); });
一个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();