我即将编写一个RSS-feed抓取器并遇到一些字符集问题。
与编码相比,加载和解析Feed非常简单。
我正在使用http.get
加载Feed,并且我将每个数据事件放在一起。
后来我用npm-lib feedparser
解析整个字符串,它对给定的字符串工作正常。
可悲的是,我习惯于在php中使用像utf8_encode()
这样的函数,而我在node.js中错过了它们,所以我很难使用当前没有按照我想要的方式使用Iconv。
没有编码,有几个utf8?-icons用于错误的字符集,用iconv,字符串被解析错误:/
目前我正在单独编码每个字符串:
//var encoding ≈ ISO-8859-1 etc. (Is the right one, checked with docs etc.)
// Shortend version
var iconv = new Iconv(encoding, 'UTF-8');
parser.on('article', function(article){
var object = {
title : iconv.convert(article.title).toString('UTF-8'),
description : iconv.convert(article.summary).toString('UTF-8')
}
Articles.push(object);
});
我应该用数据缓冲区开始编码还是稍后用完整的字符串开始编码?
谢谢!
PS:通过解析xml的头部来确定编码
在node.js中进行编码的模块更容易吗?
答案 0 :(得分:9)
您可能遇到https://groups.google.com/group/nodejs/browse_thread/thread/b2603afa31aada9c上描述的相同问题。
解决方案似乎是在使用Iconv处理缓冲区之前将响应编码设置为二进制。
相关位是
设置response.setEncoding('binary')并在调用Iconv.convert()之前将块聚合到缓冲区中。请注意,encoding = binary意味着您的数据回调将接收Buffer对象,而不是字符串。
已更新:这是我最初的回复
您确定您收到的Feed已正确编码吗?
我可以看到两个可能的错误:
Content-Type
表示charset=UTF-8
。Content-Type
标头没有说明任何内容,默认为ASCII。您应该使用Wireshark或cURL等实用程序检查Feed的内容和发送的标题。
答案 1 :(得分:1)
我认为问题可能在于将数据传递给feedparser之前存储数据的方式。没有看到你的数据事件处理程序很难说,但我猜你正在做这样的事情:
values = '';
stream.on('data', function(chunk){
values += chunk;
});
是吗?
问题在于,在这种情况下,chunk是一个缓冲区,通过使用'+'将它们全部附加在一起,你可以隐式地将缓冲区转换为字符串。
进一步研究,你应该在整个Feed中进行iconv转换,然后再通过feedparser运行,因为feedparser可能不知道其他编码。
尝试这样的事情:
var iconv = new Iconv('ISO-8859-1', 'UTF8');
var chunks = [];
var totallength = 0;
stream.on('data', function(chunk) {
chunks.push(chunk);
totallength += chunk.length;
});
stream.on('end', function() {
var results = new Buffer(totallength);
var pos = 0;
for (var i = 0; i < chunks.length; i++) {
chunks[i].copy(results, pos);
pos += chunks[i].length;
}
var converted = iconv.convert(results);
parser.parseString(converted.toString('utf8'));
});