2012-09-07 29 views
12

我在Node.JS中提取this pagethis request library,並使用cheerio解析主體。Node.JS刮碼?

在解析響應主體調用$.html()顯示,頁面的title屬性是:

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

...當它應該是:

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

我試過設置的選項請求庫包含encoding: 'utf8',但這似乎沒有任何改變。

如何保留這些字符?

+0

cheerio也可能只是顯示出[這個錯誤](https://github.com/cheeriojs/cheerio/issues/548),其不正確地輸出某些字符在某些情況下 –

回答

18

頁面似乎用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 ..                    
});                    
24

您可以使用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); 
}); 

+2

我認爲這是一個更好的答案,因爲它需要考慮響應頭。 – leesei

+1

是的,這絕對是一個更好的答案,應該是接受的答案 – Malharhak

+1

這應該是正確的答案。它巧妙地使用所有可用的手段(除了要求網站的開發者)檢測編碼並且成功! –