配色: 字号:
node爬虫之gbk网页中文乱码解决方案
2016-11-02 | 阅:  转:  |  分享 
  
node爬虫之gbk网页中文乱码解决方案



之前在用node做爬虫时碰到的中文乱码问题一直没有解决,今天整理下备忘。(PS:网上一些解决方案都已经不行了)



中文乱码具体是指用node请求gbk编码的网页,无法正确获取网页中的中文(需要转码),"gbk"和"网页中的中文"两个条件是缺一不可的。可以获取utf-8编码的网页中的中文,也可以获取gbk编码网页中的英文数字等。



举个简单的例子。获取http://acm.hdu.edu.cn/statistic.php?pid=1000排名第一的答案的username,是为"极光炫影"。刷刷刷写下如下代码:



varcheerio=require(''cheerio'')

,superagent=require(''superagent'')

,express=require(''express'');



varurl=''http://acm.hdu.edu.cn/statistic.php?pid=1000'';

varapp=express();



app.get(''/'',function(req,res,next){



superagent.get(url)

.end(function(err,sres){

varhtml=sres.text;

var$=cheerio.load(html,{decodeEntities:false});

varans=$(''.table_texttda'').eq(0).html();

res.send(ans);

});

});



app.listen(3000,function(){

console.log(''appislisteningatport3000'');

});

得到了乱码,如下:



???????

如何获取正确的中文呢?这里提供几个解决方案应急(不关心原理,只是为了应急)。



方法一:



使用superagent-charset模块(2016-08-26:如出错,请使用0.1.1版本)。



varcheerio=require(''cheerio'')

,superagent=require(''superagent-charset'')

,express=require(''express'');



varurl=''http://acm.hdu.edu.cn/statistic.php?pid=1000'';

varapp=express();



app.get(''/'',function(req,res,next){



superagent.get(url)

.charset(''gbk'')

.end(function(err,sres){

varhtml=sres.text;

var$=cheerio.load(html,{decodeEntities:false});

varans=$(''.table_texttda'').eq(0).html();

res.send(ans);

});



});



app.listen(3000,function(){

console.log(''appislisteningatport3000'');

});

使用非常简单,只需要引入superagent-charset模块,且在链式调用时加入charset参数即可。superagent-charset模块包括了superAgent模块以及iconv-lite模块。源码可以参考Github。



方法二:



直接用iconv-lite模块进行转码。



iconv-lite是一个进行编码转换的模块(node默认编码utf-8)。需要decode的编码必须是Buffer类型。



用http模块:



http.get(url,function(sres){

varchunks=[];



sres.on(''data'',function(chunk){

chunks.push(chunk);

});



sres.on(''end'',function(){

//将二进制数据解码成gb2312编码数据

varhtml=iconv.decode(Buffer.concat(chunks),''gb2312'');

var$=cheerio.loadwww.wang027.com(html,{decodeEntities:false});

varans=$(''.table_texttda'').eq(0).html();

res.send(ans);

});

});

用request模块:



request({

url:url,

encoding:null//关键代码

},function(err,sres,body){

varhtml=iconv.decode(body,''gb2312'')

var$=cheerio.load(html,{decodeEntities:false});

varans=$(''.table_texttda'').eq(0).html();

res.send(ans);

});

用iconv进行decode传入的参数必须是Buffer。



encoding-EncodingtobeusedonsetEncodingofresponsedata.Ifnull,thebodyisreturnedasaBuffer.Anythingelse(includingthedefaultvalueofundefined)willbepassedastheencowww.baiyuewang.netdingparametertotoString()(meaningthisiseffectivelyutf8bydefault).(Note:ifyouexpectbinarydata,youshouldsetencoding:null.)



iconv-lite模块能配合http模块以及request模块使用,却不能直接和superAgent模块使用。因为superAgent是以utf8去取数据,然后再用iconv转也是不行的。页面是gbk编码的,sres.text已经是decode过了的结果,也就是说它已经被转换成utf8了,再转换成buffer出来的结果必须是不正确的。

献花(0)
+1
(本文系thedust79首藏)