基于 Electron 的爬虫框架 Nightmare
作者:William
本文为原创文章,转载请注明作者及出处
Electron 可以让你使用纯 JavaScript 调用 Chrome 丰富的原生的接口来创造桌面应用。你可以把它看作一个专注于桌面应用的 Node.js 的变体,而不是 Web 服务器。其基于浏览器的应用方式可以极方便的做各种响应式的交互,接下来介绍下关于 Electron 上衍生出的框架 Nightmare。
Nightmare 是一个基于 Electron 的框架,针对 Web 自动化测试和爬虫(其实爬虫这个是大家自己给这个框架加的功能XD),因为其具有跟 PlantomJS 一样的自动化测试的功能可以在页面上模拟用户的行为触发一些异步数据加载,也可以跟 Request 库一样直接访问 URL 来抓取数据,并且可以设置页面的延迟时间,所以无论是手动触发脚本还是行为触发脚本都是轻而易举的(这边注意,如果事件具备 isTrusted 的检查的话,就无法触发了)。
使用 Nightmare
为了更快速使用 NPM 下载,可以使用淘宝的镜像地址。直接 NPM 安装Nightmare 就完成安装了(二进制的 Electron 依赖有点大,安装时间可能比较长)。
写一个简单的启动 app.js;
const Nightmare = require('nightmare')
const nightmare = new Nightmare({show: true,openDevTools: {mode: 'detach'}})nightmare.goto('https://www.hujiang.com').evaluate(function() {// 该环境中能使用浏览器中的任何对象window/document,并且返回一个promiseconsole.log('hello nightmare')console.log('5 second close window')}).wait(5000).end().then(()=> {console.log('close nightmare')})
这个脚本会在打开的浏览器的调试控制台中打印出 hello nightmare 并且在5秒后关闭,随后在运行的该脚本的中输出 close nightmare。
Nightmare原理
利用了 Electron 提供的 Browser 的环境,同时具备了 Node.js 的 I/O 能力,所以可以很方便实现一个爬虫应用。Nightmare 的官网有更详细的介绍:
大致操作:
- 浏览器事件: goto,back,forward,refresh,
- 用户事件: click,mousedown,mouseup,mouseover,type,insert,select,check,uncheck,selectscrollTo
- 向网页注入脚本: .js .css的文件类型原理是跟油猴差不多,可以编写自己的js代码注入十分方便
- wait 函数可以按照延迟时间或者一个 dom 元素的出现
- evaluate 以浏览器的环境运行的脚本函数,然后返回一个 promise 函数
一个完整的nightmare爬虫应用
我们以抓取知乎上的话题的为应用场景,需要的数据是知乎的话题信息 包含以下字段 话题名称/话题的图片/关注者数量/话题数量/精华话题数量,但是因为后三者只能在其父亲话题中包含,所以必须先抓父话题才能抓取子话题,而且这些子话题是以 hover 的形式在父话题中异步加载的,如果用Request/Superagent 需要 HTTP 传递其解析过的id才能获取,但是用Nightmare 可以直接调用其 hover 事件触发数据的加载。
第一步获取需要抓取的话题深度,默认的根是现在知乎的根话题;
/**
* 抓取对应的话题页面的url和对应的深度保存到指定的文件名中
* @param {string} rootUrl - 顶层的url
* @param {int} deep - 抓取页面的深度
* @param {string} toFile - 保存的文件名
* @param {Function} cb - 完成后的回调
*/
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('完成抓取')
})
然后进行交互函数的核心函数,注意在开始抓取前,要去看看知乎的 robots.txt 文件看看哪些能抓和抓取的间隔不然很容易 timeout 的错误。
// 获取对应的话题的信息
const cntObj = queue.shift()
const url = `https://www.zhihu.com/topic/${cntObj['id']}/hot`
const topicOriginalInfo = await nightmare.goto(url).wait('.zu-main-sidebar') // 等待该元素的出现.evaluate(function () {// 获取这块数据return document.querySelector('.zu-main-sidebar').innerHTML})
// .....若干步的操作后
// 获取其子话题的数值信息
const hoverElement = `a.zm-item-tag[href$='${childTopics[i]['id']}']`
const waitElement = `.avatar-link[href$='${childTopics[i]['id']}']`
const topicAttached = await nightmare.mouseover(hoverElement) // 触发hover事件.wait(waitElement).evaluate(function () {return document.querySelector('.zh-profile-card').innerHTML}).then(val => {return parseRule.crawlerTopicNumbericalAttr(val)}).catch(error => {console.error(error)})
cheerio 是一个 jQuery 的 selector 库,可以应用于 HTML 片段并且获得对应的DOM 元素,然后我们就可以进行对应的 DOM 操作->增删改查都可以,这边主要用来查询 DOM 和获取数据。
const $ = require('cheerio')
/** *抓取对应话题的问题数量/精华话题数量/关注者数量 */
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
}
然后一个简单的爬虫就完成了,最终获得部分数据格式如何:
{"value": "rootValue","id": "19776749","fatherId": "-1","desc": "知乎的全部话题通过父子关系构成一个有根无循环的有向图。「根话题」即为所有话题的最上层的父话题。话题精华即为知乎的 Top1000 高票回答。请不要在问题上直接绑定「根话题」。这样会使问题话题过于宽泛。","cids": ["19778317","19776751","19778298","19618774","19778287","19560891"]
},
{"id": "19778317","value": "生活、艺术、文化与活动","avatar": "https://pic4.zhimg.com/6df49c633_xs.jpg","questions": "3.7M","top-answers": "1000","followers": "91K","fid": "19776749","desc": "以人类集体行为和人类社会文明为主体的话题,其内容主要包含生活、艺术、文化、活动四个方面。","cids": ["19551147","19554825","19550453","19552706","19551077","19550434","19552266","19554791","19553622","19553632"]
},
总结
Nightmare 作为爬虫的最大优势是只需要知道数据所在页面的 URL 就可以获取对应的同步/异步数据,并不需要详细的分析 HTTP 需要传递的参数。只需要知道进行哪些操作能使得网页页面数据更新,就能通过获取更新后的 HTML 片段获得对应的数据,在 Demo 中的 Nightmare 是打开了 chrome-dev 进行操作的,但是实际运行的时候是可以关闭的,关闭了之后其操作的速度会有一定的上升。下面的项目中还包含了另外一个爬取的知乎的动态。
Demo源码地址: https://github.com/williamstar/nightmare-demo
iKcamp原创新书《移动Web前端高效开发实战》已在亚马逊、京东、当当开售。
>> 沪江Web前端上海团队招聘【Web前端架构师】,有意者简历至:zhouyao@hujiang.com <<
报名地址:http://www.huodongxing.com/event/4404706591400
基于 Electron 的爬虫框架 Nightmare相关推荐
- 基于java的爬虫框架webmagic基本使用
简单记录一下java项目实现网页爬取数据的基本使用. 需要引入的依赖 <dependency><groupId>us.codecraft</groupId>< ...
- python 写csv scrapy_scrapy爬虫框架实例一,爬取自己博客
本篇就是利用scrapy框架来抓取本人的博客,博客地址:http://www.cnblogs.com/shaosks scrapy框架是个比较简单易用基于python的爬虫框架,相关文档:http:/ ...
- Go语言爬虫框架之Colly和Goquery
文章目录 写在前面 Go语言爬虫框架之Colly和Goquery 网络爬虫 爬虫的简单算法 Colly 开始 OnHTML OnRequest / OnResponse HTMLElement Bri ...
- 基于java的网络爬虫框架(实现京东数据的爬取,并将插入数据库)
本文为原创博客,仅供技术学习使用.未经允许,禁止将其复制下来上传到百度文库等平台. 目录 网络爬虫框架 网络爬虫的逻辑顺序 网络爬虫实例教学 model main util parse db 再看ma ...
- 基于redis的简易分布式爬虫框架
代码地址如下: http://www.demodashi.com/demo/13338.html 开发环境 Python 3.6 Requests Redis 3.2.100 Pycharm(非必需, ...
- 基于SpringBoot+WebMagic实现一个的爬虫框架
点击关注公众号,实用技术文章及时了解 来源:www.jianshu.com/p/cfead4b3e34e WebMagic是一个开源的java爬虫框架.WebMagic框架的使用并不是本文的重点,具体 ...
- 【厚积薄发系列】C++项目总结11—基于Python爬虫框架的Bug规范性检查系统
需求背景: 日常开发和集成测试期间由于团队的庞大,每天测试新建的Bug和开发关闭的Bug数量也比较多,难免有些测试提Bug时其描述不规范,或者开发关Bug时备注不规范.如果每天投入人力去全部过这些Bu ...
- Python项目----基于Scrapy爬虫框架的豆瓣电影数据采集
基于Scrapy爬虫框架的豆瓣电影数据采集 项目介绍 项目简介 项目开发环境 项目需求分析 Scrapy框架 Scrapy框架基础知识 Scrapy框架安装 Scrapy框架使用 项目功能实现 爬虫主 ...
- 基于JavaGUI+Web Magic爬虫框架实现的医案采集系统 毕业文档+项目源码
资源下载地址:https://download.csdn.net/download/sheziqiong/85695155 资源下载地址:https://download.csdn.net/downl ...
- Python 爬虫框架 - PySpider
Python爬虫进阶四之PySpider的用法:http://cuiqingcai.com/2652.html 网络爬虫剖析,以Pyspider为例:http://python.jobbole.com ...
最新文章
- OA项目12:系统管理之用户管理
- 用 Flask 来写个轻博客 (13) — M(V)C_WTForms 服务端表单检验
- python掌握程度怎么判断-想要学习人工智能需要掌握Python到什么程度
- 为什么在国外刷信用卡只用签名,而国内却需要输入密码?
- python概率密度函数参数估计_EM算法求高斯混合模型参数估计——Python实现
- python request timeout_Python - aiohttp请求不断超时(Python - aiohttp requests continuously time out)...
- ++库 照片风格转换风格_如何用神经网络实现照片的风格转换
- c++ 函数指针和指针函数
- python实例 输出你好
- 高项论文(质量管理2)
- 硬盘的老化测试软件,硬盘检测工具使用方法
- “你还有什么事想问”——作为程序员如何回答面试官的问题
- JZOJ1728. Antimonotonicity
- 手机网络 G、E、H、H+、4G 都是什么意思
- Java基础教程笔记
- 记一次CTFd平台搭建
- 二代身份证读取 中控ID180 二三代身份证阅读器 Vue版本
- 语法糖(Syntactic sugar)
- 计算机数据库管理技术论文的结论,计算机数据库论文范文.doc
- ASP.NET的三层架构(DAL,BLL,UI)