关于使用cheerio抓取一个网页遇见的问题以及解决的过程

最近做开发有一个需求需要用cheerio抓取一个网页,然后将一段js脚本插入到<body>标签的末尾。然后还要保证浏览器运行正常。现在把这些遇见过的问题记录一下。
这里面就存在一个问题就是 :

Node.js默认是不支持utf-8编码的,所以抓取非 utf-8 的中文网页时会出现乱码问题,比如网易的首页编码是 gb2312,抓取时会出现乱码,百度下众大佬们的看法都是使用icon-lite 进行转码(有兴趣可以自行百度cheerio中文乱码)。(只是他们说的情况跟我这边还不太一样。我需要将网页返还给浏览器)。然后我就开始动手试了一下。思路大概是这样的:获取代理层将请求回来的html请求头header中的content-type 来判断这个网页的编码方式。然后使用iconv.decode将其进行相应的转码然后在做js替换。但是这样的话是有漏洞的,如下图

《关于使用cheerio抓取一个网页遇见的问题以及解决的过程》
有的网站开发规范性不够甚至在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}   
         
       
     

这样尝试了之后,网页中文编码的问题会解决大部分,但是有的地方还是存在中文乱码

《关于使用cheerio抓取一个网页遇见的问题以及解决的过程》
这样的问题主要是我在node进行了转码成gbk之后没有将新插入后的页面转码到初始状态,一旦被浏览器下载之后浏览器会无法识别部分js xhr的编码从而导致一部分编码。所以

newDataStr=iconv.encode($.html(), charset); 将其返回到最初的编码方式就可以了

    原文作者:愤怒的葡萄
    原文地址: https://segmentfault.com/a/1190000011502730
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞