最近做开发有一个需求需要用cheerio抓取一个网页,然后将一段js脚本插入到<body>标签的末尾。然后还要保证浏览器运行正常。现在把这些遇见过的问题记录一下。
这里面就存在一个问题就是 :
Node.js默认是不支持utf-8编码的,所以抓取非 utf-8 的中文网页时会出现乱码问题,比如网易的首页编码是 gb2312,抓取时会出现乱码,百度下众大佬们的看法都是使用icon-lite 进行转码(有兴趣可以自行百度cheerio中文乱码)。(只是他们说的情况跟我这边还不太一样。我需要将网页返还给浏览器)。然后我就开始动手试了一下。思路大概是这样的:获取代理层将请求回来的html请求头header中的content-type 来判断这个网页的编码方式。然后使用iconv.decode将其进行相应的转码然后在做js替换。但是这样的话是有漏洞的,如下图
有的网站开发规范性不够甚至在content-type 连网页的编码方式都不去声明。所以这条路是不通的只能通过抓取标签<meta charset>来确定网页相应的编码进而转码。
var newDataStr = '';
var charset="utf-8";
var arr=responseDetail.response.body.toString().match(/<meta([^>]*?)>/g);
if(arr){
arr.forEach(function(val){
var match=val.match(/charset\s*=\s*(.+)\"/);
if(match && match[1]){
if(match[1].substr(0,1)=='"')match[1]=match[1].substr(1);
charset=match[1].trim();
return false;
}
})
}
var html = iconv.decode(responseDetail.response.body, charset);
// var html = responseDetail.response.body.toString();
var $ = cheerio.load(html);
responseDetail.response.body = newDataStr;
return {response: responseDetail.response}
这样尝试了之后,网页中文编码的问题会解决大部分,但是有的地方还是存在中文乱码
这样的问题主要是我在node进行了转码成gbk之后没有将新插入后的页面转码到初始状态,一旦被浏览器下载之后浏览器会无法识别部分js xhr的编码从而导致一部分编码。所以
newDataStr=iconv.encode($.html(), charset); 将其返回到最初的编码方式就可以了
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。