国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

基于 Electron 的爬蟲(chóng)框架 Nightmare

Harriet666 / 1518人閱讀

摘要:話題精華即為知乎的高票回答。下面的項(xiàng)目中還包含了另外一個(gè)爬取的知乎的動(dòng)態(tài)。

作者:William
本文為原創(chuàng)文章,轉(zhuǎn)載請(qǐng)注明作者及出處

Electron 可以讓你使用純 JavaScript 調(diào)用 Chrome 豐富的原生的接口來(lái)創(chuàng)造桌面應(yīng)用。你可以把它看作一個(gè)專注于桌面應(yīng)用的 Node.js 的變體,而不是 Web 服務(wù)器。其基于瀏覽器的應(yīng)用方式可以極方便的做各種響應(yīng)式的交互,接下來(lái)介紹下關(guān)于 Electron 上衍生出的框架 Nightmare。

Nightmare 是一個(gè)基于 Electron 的框架,針對(duì) Web 自動(dòng)化測(cè)試和爬蟲(chóng)(其實(shí)爬蟲(chóng)這個(gè)是大家自己給這個(gè)框架加的功能XD),因?yàn)槠渚哂懈?PlantomJS 一樣的自動(dòng)化測(cè)試的功能可以在頁(yè)面上模擬用戶的行為觸發(fā)一些異步數(shù)據(jù)加載,也可以跟 Request 庫(kù)一樣直接訪問(wèn) URL 來(lái)抓取數(shù)據(jù),并且可以設(shè)置頁(yè)面的延遲時(shí)間,所以無(wú)論是手動(dòng)觸發(fā)腳本還是行為觸發(fā)腳本都是輕而易舉的(這邊注意,如果事件具備 isTrusted 的檢查的話,就無(wú)法觸發(fā)了)。

使用 Nightmare

為了更快速使用 NPM 下載,可以使用淘寶的鏡像地址。直接 NPM 安裝Nightmare 就完成安裝了(二進(jìn)制的 Electron 依賴有點(diǎn)大,安裝時(shí)間可能比較長(zhǎng))。

寫(xiě)一個(gè)簡(jiǎn)單的啟動(dòng) app.js;

const Nightmare = require("nightmare")
const nightmare = new Nightmare({
     show: true,
     openDevTools: {
         mode: "detach"
     }
 })

 nightmare.goto("https://www.hujiang.com")
   .evaluate(function() {
       // 該環(huán)境中能使用瀏覽器中的任何對(duì)象window/document,并且返回一個(gè)promise
     console.log("hello nightmare")
     console.log("5 second close window")
   })
   .wait(5000)
   .end()
   .then(()=> {
     console.log("close nightmare")
   })

這個(gè)腳本會(huì)在打開(kāi)的瀏覽器的調(diào)試控制臺(tái)中打印出 hello nightmare 并且在5秒后關(guān)閉,隨后在運(yùn)行的該腳本的中輸出 close nightmare。

Nightmare原理

利用了 Electron 提供的 Browser 的環(huán)境,同時(shí)具備了 Node.js 的 I/O 能力,所以可以很方便實(shí)現(xiàn)一個(gè)爬蟲(chóng)應(yīng)用。Nightmare 的官網(wǎng)有更詳細(xì)的介紹:

大致操作:

瀏覽器事件: goto,back,forward,refresh,

用戶事件: click,mousedown,mouseup,mouseover,type,insert,select,check,uncheck,selectscrollTo

向網(wǎng)頁(yè)注入腳本: .js .css的文件類型原理是跟油猴差不多,可以編寫(xiě)自己的js代碼注入十分方便

wait 函數(shù)可以按照延遲時(shí)間或者一個(gè) dom 元素的出現(xiàn)

evaluate 以瀏覽器的環(huán)境運(yùn)行的腳本函數(shù),然后返回一個(gè) promise 函數(shù)

一個(gè)完整的nightmare爬蟲(chóng)應(yīng)用

我們以抓取知乎上的話題的為應(yīng)用場(chǎng)景,需要的數(shù)據(jù)是知乎的話題信息 包含以下字段 話題名稱/話題的圖片/關(guān)注者數(shù)量/話題數(shù)量/精華話題數(shù)量,但是因?yàn)楹笕咧荒茉谄涓赣H話題中包含,所以必須先抓父話題才能抓取子話題,而且這些子話題是以 hover 的形式在父話題中異步加載的,如果用Request/Superagent 需要 HTTP 傳遞其解析過(guò)的id才能獲取,但是用Nightmare 可以直接調(diào)用其 hover 事件觸發(fā)數(shù)據(jù)的加載。

第一步獲取需要抓取的話題深度,默認(rèn)的根是現(xiàn)在知乎的根話題;

/** 
* 抓取對(duì)應(yīng)的話題頁(yè)面的url和對(duì)應(yīng)的深度保存到指定的文件名中
* @param {string} rootUrl - 頂層的url 
* @param {int} deep - 抓取頁(yè)面的深度 
* @param {string} toFile - 保存的文件名
* @param {Function} cb - 完成后的回調(diào) 
*/
async function crawlerTopicsFromRoot (rootUrl, deep, toFile, cb) {
  rootUrl = rootUrl ||"https://www.zhihu.com/topic/19776749/hot"
  toFile = toFile || "./topicsTree.json"
  console.time()
  const result = await interactive
      .iAllTopics(rootUrl, deep)
  console.timeEnd()
  util.writeJSONToFile(result["topics"], toFile, cb)
}

crawlerTopicsFromRoot("", 2, "", _ => {
  console.log("完成抓取")
})

然后進(jìn)行交互函數(shù)的核心函數(shù),注意在開(kāi)始抓取前,要去看看知乎的 robots.txt 文件看看哪些能抓和抓取的間隔不然很容易 timeout 的錯(cuò)誤。

// 獲取對(duì)應(yīng)的話題的信息
const cntObj = queue.shift()
const url = `https://www.zhihu.com/topic/${cntObj["id"]}/hot`
const topicOriginalInfo = await nightmare
  .goto(url)
  .wait(".zu-main-sidebar") // 等待該元素的出現(xiàn)
  .evaluate(function () {
   // 獲取這塊數(shù)據(jù)
      return document.querySelector(".zu-main-sidebar").innerHTML
  })
// .....若干步的操作后
// 獲取其子話題的數(shù)值信息
const hoverElement = `a.zm-item-tag[href$="${childTopics[i]["id"]}"]`
const waitElement = `.avatar-link[href$="${childTopics[i]["id"]}"]`
const topicAttached = await nightmare
  .mouseover(hoverElement) // 觸發(fā)hover事件
  .wait(waitElement)
  .evaluate(function () {
      return document.querySelector(".zh-profile-card").innerHTML
  })
  .then(val => {
      return parseRule.crawlerTopicNumbericalAttr(val)
  })
  .catch(error => {
      console.error(error)
  })

cheerio 是一個(gè) jQuery 的 selector 庫(kù),可以應(yīng)用于 HTML 片段并且獲得對(duì)應(yīng)的DOM 元素,然后我們就可以進(jìn)行對(duì)應(yīng)的 DOM 操作->增刪改查都可以,這邊主要用來(lái)查詢 DOM 和獲取數(shù)據(jù)。

const $ = require("cheerio")
/** *抓取對(duì)應(yīng)話題的問(wèn)題數(shù)量/精華話題數(shù)量/關(guān)注者數(shù)量 */
const crawlerTopicNumbericalAttr = function (html) {
  const $ = cheerio.load(html)
  const keys = ["questions", "top-answers", "followers"]
  const obj = {}
  obj["avatar"] = $(".Avatar.Avatar--xs").attr("src")
  keys.forEach(key => {
      obj[key] = ($(`div.meta a.item[href$=${key}] .value`).text() || "").trim()
  })
  return obj
}
/** * 抓取話題的信息 */
const crawlerTopics = function (html) {
  const $ = cheerio.load(html)
  const  obj = {}
  const childTopics = crawlerAttachTopic($, ".child-topic")  
  obj["desc"] = $("div.zm-editable-content").text() || ""
  if (childTopics.length > 0) {
      obj["childTopics"] = childTopics
  }
  return obj
}

/** * 抓取子話題的信息id/名稱 */
const crawlerAttachTopic = function ($, selector) {
  const topicsSet = []
  $(selector).find(".zm-item-tag").each((index, elm) => {
      const self = $(elm)
      const topic = {}
      topic["id"] = self.attr("data-token")
      topic["value"] = self.text().trim()
      topicsSet.push(topic)
  })
  return topicsSet
}

然后一個(gè)簡(jiǎn)單的爬蟲(chóng)就完成了,最終獲得部分?jǐn)?shù)據(jù)格式如何:

{
  "value": "rootValue",
  "id": "19776749",
  "fatherId": "-1",
  "desc": "知乎的全部話題通過(guò)父子關(guān)系構(gòu)成一個(gè)有根無(wú)循環(huán)的有向圖。「根話題」即為所有話題的最上層的父話題。話題精華即為知乎的 Top1000 高票回答。請(qǐng)不要在問(wèn)題上直接綁定「根話題」。這樣會(huì)使問(wèn)題話題過(guò)于寬泛。",
  "cids": [
      "19778317",
      "19776751",
      "19778298",
      "19618774",
      "19778287",
      "19560891"
  ]
},
{
  "id": "19778317",
  "value": "生活、藝術(shù)、文化與活動(dòng)",
  "avatar": "https://pic4.zhimg.com/6df49c633_xs.jpg",
  "questions": "3.7M",
  "top-answers": "1000",
  "followers": "91K",
  "fid": "19776749",
  "desc": "以人類集體行為和人類社會(huì)文明為主體的話題,其內(nèi)容主要包含生活、藝術(shù)、文化、活動(dòng)四個(gè)方面。",
  "cids": [
      "19551147",
      "19554825",
      "19550453",
      "19552706",
      "19551077",
      "19550434",
      "19552266",
      "19554791",
      "19553622",
      "19553632"
  ]
},
總結(jié)

Nightmare 作為爬蟲(chóng)的最大優(yōu)勢(shì)是只需要知道數(shù)據(jù)所在頁(yè)面的 URL 就可以獲取對(duì)應(yīng)的同步/異步數(shù)據(jù),并不需要詳細(xì)的分析 HTTP 需要傳遞的參數(shù)。只需要知道進(jìn)行哪些操作能使得網(wǎng)頁(yè)頁(yè)面數(shù)據(jù)更新,就能通過(guò)獲取更新后的 HTML 片段獲得對(duì)應(yīng)的數(shù)據(jù),在 Demo 中的 Nightmare 是打開(kāi)了 chrome-dev 進(jìn)行操作的,但是實(shí)際運(yùn)行的時(shí)候是可以關(guān)閉的,關(guān)閉了之后其操作的速度會(huì)有一定的上升。下面的項(xiàng)目中還包含了另外一個(gè)爬取的知乎的動(dòng)態(tài)。

Demo源碼地址: https://github.com/williamsta...

iKcamp原創(chuàng)新書(shū)《移動(dòng)Web前端高效開(kāi)發(fā)實(shí)戰(zhàn)》已在亞馬遜、京東、當(dāng)當(dāng)開(kāi)售。

>> 滬江Web前端上海團(tuán)隊(duì)招聘【W(wǎng)eb前端架構(gòu)師】,有意者簡(jiǎn)歷至:zhouyao@hujiang.com <<


報(bào)名地址:http://www.huodongxing.com/ev...

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/91739.html

相關(guān)文章

  • Electron-nightmare快速實(shí)現(xiàn)微信天氣助手Syaya

    摘要:項(xiàng)目背景龐大的用戶安裝量和恐怖的用戶使用時(shí)間,微信已成為國(guó)內(nèi)移動(dòng)互聯(lián)網(wǎng)上基礎(chǔ)設(shè)施級(jí)的應(yīng)用。以一周時(shí)間開(kāi)發(fā)的微信天氣查詢助手,就是一次技術(shù)驗(yàn)證性嘗試。但就針對(duì)微信來(lái)說(shuō),不是最好的解決方案。 項(xiàng)目背景 龐大的用戶安裝量和恐怖的用戶使用時(shí)間,微信已成為國(guó)內(nèi)移動(dòng)互聯(lián)網(wǎng)上基礎(chǔ)設(shè)施級(jí)的應(yīng)用。 以微信為平臺(tái)的客服服務(wù)有很多方式,比如訂閱號(hào),服務(wù)號(hào),小程序,但受到微信官方的限制,如果想做一個(gè)聊天群的自...

    jiekechoo 評(píng)論0 收藏0
  • 分分鐘教你用node.js寫(xiě)個(gè)爬蟲(chóng)

    摘要:爬蟲(chóng)介紹二爬蟲(chóng)的分類通用網(wǎng)絡(luò)爬蟲(chóng)全網(wǎng)爬蟲(chóng)爬行對(duì)象從一些種子擴(kuò)充到整個(gè),主要為門(mén)戶站點(diǎn)搜索引擎和大型服務(wù)提供商采集數(shù)據(jù)。 分分鐘教你用node.js寫(xiě)個(gè)爬蟲(chóng) 寫(xiě)在前面 十分感謝大家的點(diǎn)贊和關(guān)注。其實(shí),這是我第一次在segmentfault上寫(xiě)文章。因?yàn)槲乙彩乔岸螘r(shí)間偶然之間才開(kāi)始了解和學(xué)習(xí)爬蟲(chóng),而且學(xué)習(xí)node的時(shí)間也不是很長(zhǎng)。雖然用node做過(guò)一些后端的項(xiàng)目,但其實(shí)在node和爬蟲(chóng)方面...

    fanux 評(píng)論0 收藏0
  • 使用macaca進(jìn)行移動(dòng)端hybird自動(dòng)化測(cè)試(一)

    摘要:測(cè)試框架通常提供測(cè)試驅(qū)動(dòng)開(kāi)發(fā)或行為驅(qū)動(dòng)開(kāi)發(fā)的測(cè)試語(yǔ)法來(lái)編寫(xiě)測(cè)試用例。利用上面的工具基本上就可以開(kāi)始進(jìn)行測(cè)試腳本的測(cè)試工作了。下面一篇文章就會(huì)介紹如何使用來(lái)對(duì)應(yīng)用進(jìn)行測(cè)試。 部分基本概念及內(nèi)容: 單元測(cè)試: 以模塊為單元,測(cè)試你代碼的本身,確保你編寫(xiě)的模塊還有邏輯正確。只要輸入的值不變,輸出的值也應(yīng)該不發(fā)生改變 前端自動(dòng)化測(cè)試: 界面回歸測(cè)試 測(cè)試界面是否正常,包括文案,圖片等。 功能...

    CloudDeveloper 評(píng)論0 收藏0
  • 2017-09-13 前端日?qǐng)?bào)

    摘要:前端日?qǐng)?bào)精選中的垃圾收集,圖文指南十個(gè)免費(fèi)的前端開(kāi)發(fā)工具專題之遞歸如何在鏈中共享變量基于的爬蟲(chóng)框架中文譯十六進(jìn)制顏色揭秘掘金掘金小書(shū)基本環(huán)境安裝小書(shū)教程中間件對(duì)閉包的一個(gè)巧妙使用簡(jiǎn)書(shū)源碼分析掘金組件開(kāi)發(fā)練習(xí)焦點(diǎn)圖切換前端學(xué) 2017-09-13 前端日?qǐng)?bào) 精選 V8 中的垃圾收集(GC),圖文指南十個(gè)免費(fèi)的web前端開(kāi)發(fā)工具JavaScript專題之遞歸 · Issue #49 · m...

    BWrong 評(píng)論0 收藏0
  • FE.TEST-前端測(cè)試初探

    摘要:使用可以快速生成一個(gè)項(xiàng)目,其中包含了和以及覆蓋率統(tǒng)計(jì)的配置參考一個(gè)創(chuàng)建測(cè)試腳本的快速方法其他參考資料前端自動(dòng)化測(cè)試概覽測(cè)試之使用對(duì)項(xiàng)目進(jìn)行單元測(cè)試 showImg(https://segmentfault.com/img/bVbjfXr?w=600&h=317); 前言 測(cè)試可以提供快速反饋,根據(jù)測(cè)試用例覆蓋代碼,從而提升代碼開(kāi)發(fā)效率和質(zhì)量。根據(jù)投入產(chǎn)出價(jià)值,通常迭代較快的業(yè)務(wù)邏輯不做...

    Travis 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<