楔子
最近幫一個(gè)小伙伴找實(shí)習(xí)崗位,看到某公司給他發(fā)的面試題挺有意思弧岳,趁著不忙自己研究了一番凳忙,做個(gè)筆記留待以后復(fù)習(xí)。
面試題
使用 http://www.nightmarejs.org/ 爬取 https://box.jimu.com/Venus/List 第一頁項(xiàng)目數(shù)據(jù)禽炬,并生成一個(gè)數(shù)組涧卵,每個(gè)數(shù)據(jù)格式為 {name: **, rate: **, month: **, status: **}
分析
首先當(dāng)我們看到這個(gè)題目的時(shí)候應(yīng)該大概就了解這是一個(gè)爬蟲任務(wù),使用工具到指定頁面爬取數(shù)據(jù)腹尖,同時(shí)將爬取到的數(shù)據(jù)生成某種格式柳恐。
那么這道面試題的目的是要考察求職者哪些知識/能力呢?這里簡單分析了下:
- 有沒有接觸過node/npm 這個(gè)是最基礎(chǔ)的桐臊,如果這個(gè)都不知道就不用往下看了
- nightmare工具的使用
- JS數(shù)據(jù)的處理胎撤,如何生成項(xiàng)為對象格式的數(shù)組
- JS基礎(chǔ)知識晓殊,比如獲取元素断凶、分割字符串等
- 踩坑能力(這個(gè)后面再說)
好了,分析就這么多巫俺,接下來我們開始試著去解答這道面試題认烁。
開擼
首先我們應(yīng)該先了解下nightmare這個(gè)工具,官網(wǎng)鏈接http://www.nightmarejs.org/
官方說法A high-level browser automation library
,翻譯過來就是高級瀏覽器自動化庫
OK介汹,既然要使用這個(gè)庫首先要安裝却嗡,我們新建nightmare文件夾,然后執(zhí)行npm install nightmare
按照常理應(yīng)該稍等就安裝好嘹承,但是這里居然報(bào)錯(cuò)了窗价。。叹卷。錯(cuò)了撼港。。骤竹。了帝牡。
我就是在這里踩了一個(gè)坑,報(bào)錯(cuò)就是在執(zhí)行下面圖這步
百度了下發(fā)現(xiàn)蒙揣,nightmare依賴于electron靶溜,那么先安裝electron呢?不好意思,也報(bào)錯(cuò)罩息。嗤详。瞬間我就懵了,于是我試著在百度搜報(bào)錯(cuò)的代碼瓷炮,找到下面的解決方法eletron安裝卡在 node install.js断楷,原因居然是網(wǎng)速問題!U副稹冬筒!無力吐槽。茅主。
OK舞痰,按照鏈接中的方法,成功安裝nightmare诀姚。這里貼一個(gè)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);
});
有興趣可以在復(fù)制下來自已看一下效果响牛,這里重點(diǎn)看一下nightmare常用的API
- goto(url[,headers]) url為你要跳轉(zhuǎn)的網(wǎng)站url
- wait(selector) 等待某個(gè)dom元素出現(xiàn)
- type(selector[,text]) 在selector元素中輸入text文本
- click(selector) 點(diǎn)擊某個(gè)dom元素
- evaluate(fn[,agr1,agr2,...]) 在客戶端注入JS腳本并執(zhí)行 也就是你自己要封裝數(shù)據(jù)的代碼
- end() 執(zhí)行完成,等待對數(shù)據(jù)的處理
其他的API大家可以自行去官方文檔查看赫段。其實(shí)整個(gè)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);
})
大致結(jié)構(gòu)就是這樣糯笙,剩下的就是我們對要爬取的網(wǎng)站進(jìn)行結(jié)構(gòu)分析贬丛,然后寫出符合要求的代碼,我這里貼出我自己寫的代碼给涕,輕噴(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;
最終返回的數(shù)據(jù)如下圖
這里不足的地方就是返回的數(shù)據(jù)中month出現(xiàn)在第一個(gè)位置上豺憔,百度了下這是chrome瀏覽器的默認(rèn)機(jī)制,按照字母順序排序?qū)ο髮傩怨幻恚壳斑€在查找相關(guān)方法以達(dá)到題目要求
寫在最后
雖然本文寫的是nightmare工具的使用恭应,但是要想寫出最終代碼JS基礎(chǔ)知識是必不可少的,框架/庫每天都在更新耘眨,只有打牢基礎(chǔ)才能以不變應(yīng)萬變昼榛,這才是最重要的。