node爬蟲解決網頁編碼為gb2312結果為亂碼的方法


最近需要對某消防網站進行宣傳力度區域進行統計,使用一般采用的http模塊進行數據抓取的時候發現結果是亂碼,翻看原網站才發現,該消防網站是gb2312的編碼,而http模塊爬出的數據不能進行gbk解析,因此本片文章主要為解決用node對網站編碼為gb2312爬蟲時得到亂碼這一問題。

1. 使用工具:webstorm,node開發神器,強烈推薦

2. 再說思路:先對新聞列表頁面進行爬蟲,再對抓到的鏈接一一進行目標網頁的標題顯示和新聞來源的統計,本頁面新聞統計完畢后再跳轉下一頁,重新進行該過程。

備注:至於為什么不采用的“先對一篇文章進行目標內容獲取,再對‘下一篇’進行地址獲取”這個方式,是因為,該消防網站的下一篇與新聞列表順序不符 /手動微笑臉

3. 代碼如下:

 1 var http = require("http");
 2 var fs = require("fs");
 3 var cheerio = require("cheerio");
 4 var charset = require("superagent-charset");
 5 var agent = require("superagent");
 6 charset(agent); // 
 7 
 8 var obj = {};
 9 
10 var page = 1;   // 開始頁碼
11 var MAXPAGE = 38;   // 結束頁碼
12 
13 var num = 0;    // 記錄條數
14 
15 var url = "http://www.cqfire.com/xxzx/news.asp?class1=%D0%C2%CE%C5%D6%D0%D0%C4&class2=%CA%D0%C4%DA%D0%C2%CE%C5";
16 
17 startRequest(url + "&PageNo=" + page, 0);
18 function startRequest(site, flag){
19     var html = '';
20     var resStr = '';
21     agent.get(site).charset('gbk').end((err, res) => {
22         html = res.text;
23         var $ = cheerio.load(html);  // 采用cheerio模塊解析html
24 
25         if(flag == 0){
26             // 如果flag為0,表示列表頁面,需要對頁面進行解析
27             var eles = $("a").not(".nav_menu").not(".left_menu_class").not(".copy_menu");
28             for(var i = 0 ; i < eles.length; i ++){
29                 // 將提取出a中的url傳入flag為1的本方法中
30                 var target = "http://www.cqfire.com/" + eles.eq(i).attr("href");
31                 startRequest(target, 1);
32             }
33 
34             if(page < MAXPAGE){
35                 // 如果未達到最大頁數,則進行下一頁,傳入flag為0
36                 page ++;
37                 console.log(url + "&PageNo=" + page);
38                 startRequest(url + "&PageNo=" + page, 0);
39             }
40         }else{
41             // 如果flag為1,則表示為具體新聞頁面,需要對標題和來源進行提取
42             // 獲取新聞標題
43             var title = $("span.STYLE2").text().trim();
44             // 獲取新聞來源
45             var origin = $("span.STYLE2").parent().parent().parent().parent().parent().next().find("td[align='middle']").text().trim();
46             var from = origin.split(" ")[0].split(":")[1];
47 
48             num++;  // num表示當前新聞的條數
49             console.log(num +"-->"+title);
50 
51             // 將來源為key,統計個數為value存入結果對象中
52             if(!obj[from]){
53                 obj[from] = 0;
54             }
55             obj[from] += 1;
56 
57             for(var key in obj){
58                 resStr += key + '\t' + obj[key] + '\n';
59             }
60             // 將結果以字符串的形式存入txt中,這里要使用同步方法,否則輸出會出現很多null,但是txt文檔中統計結果與同步方法一致,這里不解
61             fs.writeFileSync('./data/result.txt', resStr, 'utf-8', function (err) {
62                 console.log(err);
63             })
64         }
65 
66     })
67 
68 }

4. 使用的是superagent,superagent-charset兩個插件,在第21行使用charset()方法,也可以不傳入參數表示自動檢測網頁的編碼方式;

5. 利用cheerio包對目標網頁DOM結構進行解析,獲取目標內容的方法與jQuery方法一致

 

總結:

利用node進行爬蟲的關鍵點有三點:

1. 如何獲取“下一頁”的地址,本方法中使用的網頁中國PageNo參數,這一點需要在確定爬蟲方式之后,找到規律

2. 在目標頁如何獲取目標內容,這需要對文檔結構進行觀察,本方法中使用的cherrio包,其獲取目標內容的方法與jQuery一致,也是node爬蟲的主流選擇

3. 如何結束遞歸,本方法是確定最大頁數,也可以設置最大條數,也可以進行手動結束遞歸,但要注意做好已經爬好的數據的記錄


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM