關於使用cheerio抓取一個網頁碰見的問題以及解決的過程

最近作開發有一個需求須要用cheerio抓取一個網頁,而後將一段js腳本插入到<body>標籤的末尾。而後還要保證瀏覽器運行正常。如今把這些碰見過的問題記錄一下。
這裏面就存在一個問題就是 :html

Node.js默認是不支持utf-8編碼的,因此抓取非 utf-8 的中文網頁時會出現亂碼問題,好比網易的首頁編碼是 gb2312,抓取時會出現亂碼,百度下衆大佬們的見解都是使用icon-lite 進行轉碼(有興趣能夠自行百度cheerio中文亂碼)。(只是他們說的狀況跟我這邊還不太同樣。我須要將網頁返還給瀏覽器)。而後我就開始動手試了一下。思路大概是這樣的:獲取代理層將請求回來的html請求頭header中的content-type 來判斷這個網頁的編碼方式。而後使用iconv.decode將其進行相應的轉碼而後在作js替換。可是這樣的話是有漏洞的,以下圖node

clipboard.png
有的網站開發規範性不夠甚至在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}

這樣嘗試了以後,網頁中文編碼的問題會解決大部分,可是有的地方仍是存在中文亂碼網站

clipboard.png
這樣的問題主要是我在node進行了轉碼成gbk以後沒有將新插入後的頁面轉碼到初始狀態,一旦被瀏覽器下載以後瀏覽器會沒法識別部分js xhr的編碼從而致使一部分編碼。因此編碼

newDataStr=iconv.encode($.html(), charset); 將其返回到最初的編碼方式就能夠了spa

相關文章
相關標籤/搜索