Node.JS抓取编码问题?

16

我在Node.JS中使用这个请求库获取此页面,并使用cheerio解析页面内容。

在解析后的响应体上调用$.html()函数,可以看到页面的标题属性为:

<title>Le Relais de l'Entrec?te</title>

...应该是:

<title>Le Relais de l'Entrecôte</title>

我尝试设置请求库的选项以包括encoding: 'utf8',但似乎没有任何改变。

如何保留这些字符?


cheerio 也可能会展示 这个 bug,在某些情况下会错误地输出某些字符。 - Dan Dascalescu
2个回答

33

你可以使用 iconv (或更好的 iconv-lite) 进行转换,但要检测编码,建议使用 charsetjschardet 模块。以下是它们同时运作时的示例:

var charset = require('charset'),
    jschardet = require('jschardet'),
    Iconv = require('iconv').Iconv;

request.get({url: 'http://www.example.com', encoding: 'binary'}, function(err, res, body) {
    var enc = charset(res.headers, body) || jschardet.detect(body).encoding.toLowerCase();

    if(enc !== 'utf8') {
        var iconv = new Iconv(enc, 'UTF-8//TRANSLIT//IGNORE');
        body = iconv.convert(new Buffer(body, 'binary')).toString('utf8');
    }

    console.log(body);
});


3
我认为这是一个更好的答案,因为它考虑了响应头信息。 - leesei
2
是的,这绝对是更好的答案,应该被接受。 - nialna2
2
这应该是正确的答案。它巧妙地利用了所有可用的手段(除了询问网站开发者)来检测编码,并且成功了! - dkasipovic
请注意,jschardet v2.2.1 将返回 'UTF-8',在将其转换为小写后不会匹配 'utf8'。 - dpmott

23

页面似乎使用了 iso-8859-1 编码。您需要告诉 request 返回一个未编码的缓冲区,方法是传递参数 encoding: null 并使用类似node-iconv 的工具进行转换。

如果您正在编写通用爬虫程序,则必须找出如何检测每个页面的编码以正确解码它,否则以下内容应该适用于您的情况:

var request = require('request');                                               
var iconv = require('iconv');                                                   

request.get({                                                                   
  url: 'http://www.relaisentrecote.fr',                                         
  encoding: null,                                                               
}, function(err, res, body) {                                                   
  var ic = new iconv.Iconv('iso-8859-1', 'utf-8');                              
  var buf = ic.convert(body);                                                   
  var utf8String = buf.toString('utf-8');  
  // .. do something with utf8String ..                                                                             
});                                                                             

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接