Nodejs优秀工具之nightmare

楔子

最近帮一个小伙伴找实习岗位,看到某公司给他发的面试题挺有意思,趁着不忙自己研究了一番,做个笔记留待以后复习。

面试题

使用 http://www.nightmarejs.org/ 爬取 https://box.jimu.com/Venus/List 第一页项目数据,并生成一个数组,每个数据格式为 {name: **, rate: **, month: **, status: **}

分析

首先当我们看到这个题目的时候应该大概就了解这是一个爬虫任务,使用工具到指定页面爬取数据,同时将爬取到的数据生成某种格式。
那么这道面试题的目的是要考察求职者哪些知识/能力呢?这里简单分析了下:

  • 有没有接触过node/npm 这个是最基础的,如果这个都不知道就不用往下看了
  • nightmare工具的使用
  • JS数据的处理,如何生成项为对象格式的数组
  • JS基础知识,比如获取元素、分割字符串等
  • 踩坑能力(这个后面再说)
    好了,分析就这么多,接下来我们开始试着去解答这道面试题。

开撸

首先我们应该先了解下nightmare这个工具,官网链接http://www.nightmarejs.org/
官方说法A high-level browser automation library,翻译过来就是高级浏览器自动化库
OK,既然要使用这个库首先要安装,我们新建nightmare文件夹,然后执行npm install nightmare 按照常理应该稍等就安装好,但是这里居然报错了。。。错了。。。了。
我就是在这里踩了一个坑,报错就是在执行下面图这步

Nodejs优秀工具之nightmare_第1张图片
image.png

百度了下发现,nightmare依赖于electron,那么先安装electron呢?不好意思,也报错。。瞬间我就懵了,于是我试着在百度搜报错的代码,找到下面的解决方法 eletron安装卡在 node install.js,原因居然是网速问题!!!无力吐槽。。
OK,按照链接中的方法,成功安装nightmare。这里贴一个nightmare在github上的示例:

var Nightmare = require('nightmare');       
var nightmare = Nightmare({ show: true });

nightmare
  .goto('https://duckduckgo.com')
  .type('#search_form_input_homepage', 'github nightmare')
  .click('#search_button_homepage')
  .wait('#zero_click_wrapper .c-info__title a')
  .evaluate(function () {
    return document.querySelector('#zero_click_wrapper .c-info__title a').href;
  })
  .end()
  .then(function (result) {
    console.log(result);
  })
  .catch(function (error) {
    console.error('Search failed:', error);
  });

有兴趣可以在复制下来自已看一下效果,这里重点看一下nightmare常用的API

  • goto(url[,headers]) url为你要跳转的网站url
  • wait(selector) 等待某个dom元素出现
  • type(selector[,text]) 在selector元素中输入text文本
  • click(selector) 点击某个dom元素
  • evaluate(fn[,agr1,agr2,...]) 在客户端注入JS脚本并执行 也就是你自己要封装数据的代码
  • end() 执行完成,等待对数据的处理
    其他的API大家可以自行去官方文档查看。其实整个API看下来还是挺简单的,那么我们就直接开始我们的需求。
var Nightmare = require("nightmare");
var nightmare = Nightmare({show:false})
nightmare
    .goto("https://box.jimu.com/Venus/List")
        .evaluate(function(){
                //  ourcode
        })
.end()
    .then(function(result){
        console.log(result);
    })
    .catch(function(error){
        console.log(error);
    })

大致结构就是这样,剩下的就是我们对要爬取的网站进行结构分析,然后写出符合要求的代码,我这里贴出我自己写的代码,轻喷(o(╯□╰)o)

var links = document.querySelectorAll(".project");
        var listArr = [],
            listObj = {},
            len = links.length;
         for(let i = 0;i < len;i++){
                listObj.name = links[i].getElementsByClassName("title")[0].innerText;
                listObj.rate = links[i].getElementsByClassName("invest-item-profit")[0].innerText + "%";
                listObj.month = links[i].getElementsByClassName("time")[0].getElementsByClassName("num")[0].innerText + links[i].getElementsByClassName("time")[0].getElementsByClassName("tip")[0].innerText.slice(-2,-1);
                listObj.status = links[i].getElementsByClassName("more-title")[0].innerHTML;
                listArr.push(listObj);
                listObj = {};
            } 
        return listArr;

最终返回的数据如下图

Nodejs优秀工具之nightmare_第2张图片
image.png

这里不足的地方就是返回的数据中month出现在第一个位置上,百度了下这是chrome浏览器的默认机制,按照字母顺序排序对象属性,目前还在查找相关方法以达到题目要求

写在最后

虽然本文写的是nightmare工具的使用,但是要想写出最终代码JS基础知识是必不可少的,框架/库每天都在更新,只有打牢基础才能以不变应万变,这才是最重要的。

你可能感兴趣的:(Nodejs优秀工具之nightmare)