通过代码学习nodejs的一些笔记。
本周主要用node实现一个小爬虫程序:
- 抓取 https://cnodejs.org/ 当天的帖子信息:url、用户、标题、发布时间、分类。
- 获取所有HTML;
- 解析获取到的HTML,提取出所需信息。
-
使用node提供的https模块,请求HTML文件。
function getAllHtml(page){ https.request({ host: url, path: '/?tab=all&page=' + page, method: 'GET', }, function (response) { let data = ''; response.on('data', function (buff) { data += buff; }); response.on('end', function () { let htmlArray = data.toString(); parseHtml(htmlArray); }); }).on('error', function (e) { console.log('error:', e.message); }).end(); }
-
根据已知的HTML文件DOM结构,把获取到的HTML文件解析出需要的信息。目前可以解析HTML的插件不少,比如cheerio、 jsdom、htmlparser2、parse5等等。这里使用cheerio。
function parseHtml(html) { let $ = cheerio.load(html); let cells = $('.cell'); cells && cells.each(function (index, item) { let cell = $(item); let user = cell.find('.user_avatar').attr('href').split('/user/')[1]; let url = cell.find('.topic_title').attr('href'); let title = cell.find('.topic_title').attr('title'); let time = cell.find('.last_active_time').text(); let type = cell.find('.topic_title_wrapper').children().first().text(); if (time.indexOf('秒') !== -1 || time.indexOf('分钟') !== -1 || time.indexOf('小时') !== -1) { info.push({ user: user, url: url, title: title, time: time, type: type }) } }) }
其中,cheerio用法来自https://github.com/cheeriojs/cheerio,获取想要的节点内容。
- 首先,需要载入HTML,载入的方式有多种,选择合适的一种。
- 然后使用cheerio的选择器,首先选择出所有帖子的数据集。
- 接着对数据集进行遍历,根据DOM结构,分离出需要的信息
在实现过程中,出现以下问题:
- cell使用find方法为undefined,cell本身不为空。
- 要求时间是当天,抓取html页面是根据page,无法知道时间。
-
对于第一个问题,我还找了蛮久,因为看cell不为空。其实是我粗心,以为each参数顺序和forEach一样,其实是反的。cell是一个cheerio的初始化对象,所以不为空。
-
对于第二个问题,只能获取所有page的html,但不知道total page数,好尴尬。
这次只是实现一个小爬虫,其实这里面还有很多东西可以研究,比如爬取更复杂的页面、不同网站可能遇到认证、编码、代码优化、性能优化等等。
已经感受到node的魅力啦! 最后附上git地址:https://github.com/AdamantG/node-test