最近个人好友在写项目的时候常常会抱怨数据的来源,的确对于一个前端来讲,数据接口数据资源永远是Mock。网上看不少大神python,node玩的飞起。但自我感受,并无一套好的流程方案能够走进咱们开发的流程中。为了帮助个人好友而且须要数据的你来讲,能够仔细的看看整套流程。由于我也是个前端,因此知道你们须要的是什么以及处理的方案。那么就跟着我一块儿学习下吧!css
学海无涯,我但愿你能够跟着个人思路简单的实现下,与其临渊羡鱼,不如退而结网。文章中我会详细讲解每一步的操做和细节,nodejs一些经常使用的API,以及koa2简单的语法,你们也能够由此文开始你的koa2学习,真的很好用的一个web框架。另外文章中也会讲解数据跨域请求的方案和具体实现,最后就是数据的格式化处理和基本请求。三强上场,共唱一出好戏。html
http.request:node http 模块的request方法能够做为httpclient向服务器发起http请求,爬虫须要向目标连接发起http请求来得到页面信息前端
建立一个新文件夹,进入以后,咱们初始化生产package.json文件vue
npm init -y
生成的package.json后,安装koa包,这里咱们用npm来安装node
npm initall --save koa
其余的依赖跟上面同样的方式安装,这里就不展开了,写在一块儿python
npm install --save koa-static npm install --save koa2-cors
唱戏以前必定要排练好,要有剧本,每一个人都应该清楚的知道本身的身份和出场时间。那么每次上台时都须要排练下,热下身。这样才能演绎一出好戏。咱们也同样,先来一端代码热热身。在咱们的文件夹下新建一个demo01.js吧,而后输入下面一端代码jquery
var http = require('http') // Node.js提供了http模块,用于搭建HTTP服务端和客户端 var url = 'http://www.runoob.com/nodejs/nodejs-tutorial.html'; //输入任何网址均可以 http.get(url,function(res){ //发送get请求 var html='' res.on('data',function(data){ html += data //字符串的拼接 }) res.on('end',function(){ console.log(html) }) }).on('error',function(){ console.log('获取资源出错!') })
打开终端,执行node demo01.js命令,你就会看到这个网页全部的html结构,这也是为咱们的大戏敲响了第一声锣鼓。ios
在上面咱们能够获得这个网页的全部HTML,这就觉得着咱们能够在这个HTML里去寻找咱们须要的资源。nodejs为此提供了一种很是快捷而且方便的cheerio API。前言部分已介绍了它的功能,这里就直接演示怎么操做。
引入咱们的cheeriogit
const cheerio = require('cheerio')
引用以后咱们在把它包装一下,让他更像jquery,jquery的有点就是对dom操做的很是的简单程序员
var $ = cheerio.load(html)
接下来就是去咱们的html中寻找咱们须要的资源了,每一个人的需求都是不同的,这里就以案例为主,去获取imooc上的视频资源。为了让咱们的主体(前面热身提到的)可读性良好,所以咱们把这部分封装成一个函数,就收html为参数.
function filterChapters(html) { var $ = cheerio.load(html) var chapters = $('.course-wrap') //在html里寻找咱们须要的资源的class var courseData = [] // 建立一个数组,用来保存咱们的资源 chapters.each(function(item) { //遍历咱们的html文档 var chapter = $(this) var chapterTitle = chapter.find('h3').text().replace(/\s/g, "") var videos = chapter.find('.video').children('li') //使用childern去获取下个节点 var chapterData = { chapterTitle: chapterTitle, videos: [] } videos.each(function(item) { //遍历视频中的资源,title,id, url var video = $(this).find('.J-media-item') //一样的方式找到咱们须要的class部分 var videoTitle = video.text().replace(/\n/g, "").replace(/\s/g, ""); var id = video.attr('href').split('video/')[1]; //切割咱们的href的到咱们的id var url = `http://www.imooc.com/video/${id}` // es6字符串模板的方式去经过id拿到咱们的视频url chapterData.videos.push({ title:videoTitle, id: id, url: url }) }) courseData.push(chapterData) }) return courseData //返回咱们须要的资源 }
采坑记录:咱们获得的资源可能有换行符或者空格符之类的,若是不去除的话后面的json格式就会出错,而却夹带着n等符号,这显然不是咱们须要的格式和数据,所以在咱们.text()的时候应该把这些html自带的n,t等去除。使用正则和replace API。
var videoTitle = video.text().replace(/n/g, "").replace(/s/g, "");
拿到咱们须要的资源以后,并不会是一个json对象的形式,所以咱们还须要加工一次,
var courseData = filterChapters(html) let content = courseData.map((o)=>{ return JSON.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) throw new Error ('写文件失败'+err); console.log("成功写入文件") })
大功告成,咱们去看看咱们的成果,打开index.json文件咱们能够看到咱们拍下来的数据了
是否是咱们须要的数据呢!!!窃喜窃喜。nodejs演技十分的不错!
koa 是什么,借用官网的一句话:koa --基于Node.js平台的下一代web开发框架。
它很小,但扩展性很强。Koa给人一种干净利落的感受,体积小、编程方式干净。为何我要用一下他呢,nodejs同样能够完成我接下的操做。的确咱们也能够用creatServer去建立一个服务,可是做为程序员应该去摄取新知识,尤为是好的受欢迎的,这样才能保持与时俱进!其KOA2真的挺简单,比起node来讲。前文已导入了koa,这里还会直接讲如何使用。不懂的同窗我以为能够看看koa官网了解下基本的使用。
对于一个mock用到快吐的我来讲,毫不能忍受爬来的数据又放到mock上。因而开启咱们的koa2之旅。
const app = new Koa() const staticPath = './static' //静态文件夹 app.use(static( path.join( __dirname, staticPath) ////设置静态文件地址,这里原本想用路由的可是以为不必启动。 )) app.use( async ( ctx ) => { //在咱们的页面输出hello world,这里只是为了演示下koa的入门。咱们访问咱们的静态资源在地址栏加/index.json ctx.body = 'hello world' }) app.listen(3000, () => { //启动一个3000的端口 console.log('[demo] static-use-middleware is starting at port 3000') })
不能跨域访问,这怎么搞。爬下的数据弄了半天,被chroml拦截。ajax跨域访问是一个老问题了,解决方法不少,比较经常使用的是JSONP方法,JSONP方法是一种非官方方法,并且这种方法只支持GET方式,不如POST方式安全。所以咱们选择在服务器端更改,引用咱们的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') { return false; } return '*'; },
因为本文重在介绍爬虫而且我最近在写一个vue项目就用这个演示下axios的基本请求,想了解更多axios能够去axios github上理解更多的用法。
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让你的请求变得更优雅,这里就不作处理。主要是太懒了... }
请求完数据,咱们在控制台打印输出了咱们的data
引用文字
三者一块儿的功力实在是太强悍了。让咱们看到了一出精彩绝伦的好戏。你看到这里说明你也是想要了解的。那为何不本身动手实现下,个人项目在我github上,你能够clone下来,其实并发不了多少时间的。能够解决之后你数据来源的烦恼,欢乐而不为呢?你也能够跟着整篇文章的思路本身实现,期待你更优秀的做品和我分享。欢迎在下方评论以及留言。我是个大三的孩子,(不能说孩子要说学生)最近在找实习公司。但愿有推荐的也能够介绍介绍。下篇文章我会推出个人vue实战做品。你也能够关注我,跟我一块儿学习。乐与分享,收获友谊。