最近需要对某消防网站进行宣传力度区域进行统计,使用一般采用的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. 如何结束递归,本方法是确定最大页数,也可以设置最大条数,也可以进行手动结束递归,但要注意做好已经爬好的数据的记录
时间: 2024-12-28 02:47:55