最近小伙伴们在写项目的时候经常吐槽数据的来源。确实,对于一个前端来说,数据接口数据资源永远是Mock。在网上看过很多很棒的python和node。但是感觉没有好的流程方案可以进入我们开发的流程。为了帮助需要数据的朋友和你,大家可以仔细看看整个过程。因为我也是做前端的,所以我知道大家需要什么,怎么去处理。那就跟着我一起学习吧!前言学海无涯,希望你能按照我的思路,简单实现。与其羡深渊之鱼,不如退而结网。在文章中,我会详细讲解每一步的操作和细节,nodejs的一些常用API,以及koa2的简单语法。你也可以从这篇文章开始你的koa2学习。这是一个非常易于使用的Web框架。此外,文章还将讲解数据跨域请求的方案和具体实现,最后是数据格式化和基本请求。前三名一起弹唱一出好戏。技术栈http.request:节点http模块的request方法,可以作为httpclient向服务端发起http请求。爬虫需要向目标链接发起http请求获取页面信息cheerio:通过http请求的页面信息,由于没有浏览器dom解析,看起来是一串乱七八糟的字符串,实在是不好。幸运的是,我们可以使用cheerio库将其解析成dom,这样我们就可以使用类似jquery的语法来分析页面信息koa2-static:koa-static静态资源中间件,可以访问我们项目中的静态资源:实现数据跨域ajax请求,该方法的关键是在服务端配置axios+promise:由于node的单线程特性,不可避免的使用了很多异步编程的写法,嵌套回调写法已经很low了,具体实现我们试试promise的写法1.环境设置新建一个文件夹,进入后我们初始化npminit-y生成的productionpackage.json文件package.json最后安装koa包裹。这里我们使用npm来安装npminitall--savekoa。其他依赖的安装方式同上,这里不再展开。一起写npminstall--savekoa-staticnpminstall--savekoa2-cors2.用nodejs热身。在搭建爬虫基石之前,一定要排练好,有剧本。每个人都应该清楚自己的身份和上场时间。然后每次上台都要排练下半身热身。只有这样,才能演出好戏。我们也是一样的,先热热代码吧。在我们的文件夹下新建一个demo01.js,然后输入下面的代码runoob.com/nodejs/nodejs-tutorial.html';//可以输入任意URLhttp.get(url,function(res){//发送get请求varhtml=''res.on('data',function(data){html+=data//字符串拼接})res.on('end',function(){console.log(html)})}).on('error',function(){console.log('Getresourceerror!')})打开终端,执行nodedemo01.js命令,你会看到这个网页的所有html结构,这也是我们的大剧《锣鼓声》的初音。开始我们的表演,我们可以得到这个网页的所有HTML,也就是说我们可以在这个HTML中找到我们需要的资源。nodejs为此提供了非常快速方便??的cheerioAPI。它的功能在前言中已经介绍过了,这里直接演示如何操作。在介绍了我们的cheerioconstcheerio=require('cheerio')参考之后,我们将把它包装起来,让它更像jquery。jquery的优点是对dom的操作非常简单。var$=cheerio.load(html)接下来就是去我们的html中寻找我们需要的资源。每个人的需求都不一样。这里重点介绍获取imooc上的视频资源的案例。为了使我们的主体(在之前的热身中提到)具有可读性,我们将这部分封装成一个函数,并接受html作为参数。functionfilterChapters(html){var$=cheerio.load(html)varchapters=$('.course-wrap')//在html中寻找我们需要的资源类varcourseData=[]//创建一个数组来保存我们的资源chapters.each(function(item){//遍历我们的html文档varchapter=$(this)varchapterTitle=chapter.find('h3').text().replace(/\s/g,"")varvideos=chapter.find('.video').children('li')//使用childern获取下一个节点varchapterData={chapterTitle:chapterTitle,videos:[]}videos.each(function(item){//遍历video中的资源,title,id,urlvarvideo=$(this).find('.J-media-item')//同理找到我们需要的class部分varvideoTitle=video.text().replace(/\n/g,"").replace(/\s/g,"");varid=video.attr('href').split('video/')[1];//将我们的href拆分为我们的idvarurl=`http://www.imooc.com/video/${id}`//es6字符串模板方式通过id获取我们的视频urlchapterData.videos.push({title:videoTitle,id:id,url:url})})courseData.push(chapterData)})returncourseData//返回我们需要的资源}挖矿记录:我们拿到的资源可能有换行或者空格是的,如果是不去掉,后面的json格式会出错,但是里面包含了n等符号,显然不是我们需要的格式和数据,所以我们在.text()的时候要把html自带的n,t和使用常规API和替换API删除等等。varvideoTitle=video.text().replace(/n/g,"").replace(/s/g,"");表演结束,获取到我们需要的资源后,不会是json对象形式,所以需要重新处理,varcourseData=filterChapters(html)letcontent=courseData.map((o)=>{returnJSON.stringify(o)//JSON.stringify()方法用于将JavaScript值转换为JSON字符串。})现在我们有了真正想要的资源,下一步就是保存它。创建一个新的index.json文件来存储我们的资源。使用nodejs的fs来写入我们的数据,这里简单介绍一下fs,fs应该是node中最常用的API,里面包含了很多我们需要的操作,比如读、写、下载。有兴趣的同学可以看看文档fs。我们引入fs将爬取到的数据写入到我们的index.json文件夹中fs.writeFile('./index.json',content,function(err){//文件路径,写入内容,回调函数if(err)thrownewError('写入文件失败'+err);console.log("成功写入文件")})大功告成,看看我们的结果,打开index.json文件可以看到我们的是抓包data我们需要的数据?!!高兴地。nodejs演技很好!2、现场的koa2是什么?借用官网的一句话:koa——一个基于Node.js平台的下一代web开发框架。它很小,但可扩展性很强。Koa给人一种干净的感觉,体积小,编程干净。我为什么要用他?Nodejs也可以完成我接下来的操作。的确,我们也可以使用creatServer来创建一个服务,但是作为程序员,我们应该吸收新的知识,尤其是好的、流行的,才能与时俱进!与node.js相比,它的KOA2非常简单。Koa在上一篇文章中已经导入,这里就直接说明如何使用。不懂的同学,我觉得可以去koa官网看看基本的用法。思考1:拿到我们需要的资源后,怎么挂到网上去请求呢?easyMock,把爬取的数据复制一份,直接扔到Mock里面,会帮你创建一个url,你就可以访问了。koa2启动一个服务并将我们的数据挂载到它上面。访问端口号我用mock很快,不忍心把爬取的数据再放到mock上。于是开始了我们的koa2之旅。constapp=newKoa()conststaticPath='./static'//静态文件夹app.use(static(path.join(__dirname,staticPath)////设置静态文件地址,这里我本来想用路由但是我觉得没有必要启动。))app.use(async(ctx)=>{//在我们的页面输出helloworld,这里只是为了演示引入koa。我们在地址栏访问我们的静态资源,添加/index.jsonctx.body='helloworld'})app.listen(3000,()=>{//启动一个3000端口console.log('[demo]static-use-middlewareisstartingatport3000')})思考2:本来很开心的用自己的端口请求数据,却发现不能跨域访问,怎么办。爬下来的数据,摆弄了半天,被chroml拦截了。Ajax跨域访问是个老问题。有很多解决方案。JSONP方式比较常用。JSONP方式是非官方方式,这种方式只支持GET方式,安全性不如POST方式。所以我们选择在服务端改,引用我们的koa2-cors。koa2-cors的自我理解:CORS将请求分为简单请求和非简单请求。可以简单的认为简单的请求就是get和post请求,没有额外的请求头,如果是post请求,请求格式不能是application/json(因为我对这块理解不深,如果有是一个错误,希望有人能指出错误并提出修改建议)。其余的put和post请求,Content-Type为application/json的请求,自定义请求头的请求都是非简单请求。简单请求的配置非常简单。如果仅仅通过完成响应就达到了目的,那么只需要在响应头中配置Access-Control-Allow-Origin即可解决问题。app.use(cors({origin:function(ctx){if(ctx.url==='/test'){returnfalse;}return'*';},3.axios登场由于本文重点关于爬虫的介绍,最近在写一个Vue项目,我会用这个来演示axios的基本请求,如果想了解axios更多的知识,可以去axiosgithub了解更多的用法。methods:{getdata(){axios.get('http://localhost:3000/index.js',{//访问我们创建的端口dataType:'json',contentType:"application/json",crossDomain:true,}).then(function(response){console.log(response.data);}).catch(function(err){console.log(err);});}},mounted(){this.getdata()//可以使用async/awiter让你的请求更优雅,这里就不做了。主要是我太懒了。。。}请求完数据后,我们在控制台打印出我们的数据引用文本结论:三者的组合技能真的很厉害。让我们看一场精彩的表演。如果你看到这个,说明你也想知道。那为什么不自己实现呢,我的项目在我的github上,你可以clone,不过贴出来也不用花多少时间。能解决你以后数据源的烦恼,何乐而不为呢?大家也可以按照整篇文章的思路自己实现,期待与我分享你们更多的优秀作品。欢迎在下方评论留言。我是一名大三学生,(不能说是小孩就是学生)最近在找实习公司。希望有推荐的也可以介绍一下。在下一篇文章中,我将推出我的实际Vue作品。你也可以关注我,和我一起学习。享受分享,收获友谊。
