首页 > 代码库 > node爬虫解决网页编码为gb2312结果为乱码的方法

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. 如何结束递归,本方法是确定最大页数,也可以设置最大条数,也可以进行手动结束递归,但要注意做好已经爬好的数据的记录

node爬虫解决网页编码为gb2312结果为乱码的方法