您的位置:首页 > 理论基础 > 计算机网络

nodejs入门(一)URL与HTTP

2015-10-16 16:08 721 查看

相关

官网:https://nodejs.org/en/

API:https://nodejs.org/api/

慕课网:进击Node.js基础(一):http://www.imooc.com/learn/348

说点啥

一直想做一个属于自己的应用。于是“被迫”就来学一门后台相关的语言。以前从没搞过相关的,node应该算是我的启蒙语言了吧。

js嘛 很难想不到JavaScript,学会了这个,是不是再学Web就简单了?

我是从慕课网看视频学起的,这篇文章算是学习笔记吧,视频地址见下面的相关

API

URL

对应api地址:https://nodejs.org/api/url.html

对应慕课网视频地址:http://www.imooc.com/video/6710

api里乍一看啥玩意儿啊,全是英文,然后我就去看视频了。看完视频反过来再看api,卧槽,原来前面那一大坨Example是这个啊,哈哈,我们一起来看

我们在cmd中输入node,回车,便进入了nodejs的环境。 输入url,回车,我们会看到:

{
parse: [Function: urlParse],
resolve: [Function: urlResolve],
resolveObject: [Function: urlResolveObject],
format: [Function: urlFormat],
Url: [Function: Url]
}


这就是我们url的几个方法。其中最重要的当属 parse 了。 api中如下,我也不懂。。。:

url.parse(urlStr, [parseQueryString], [slashesDenoteHost])


parse基础

作用:解析 url

输入:url.parse(‘http://www.flowerfat.com‘)

输出:

{
protocol: 'http:',
slashes: true,
auth: null,
host: 'www.flowerfat.com',
port: null,
hostname: 'www.flowerfat.com',
hash: null,
search: null,
query: null,
pathname: '/',
path: '/',
href: 'http://www.flowerfat.com/'
}


跟着视频走到这里的时候,虽然scott哥说了每个的含义,不过还是没咋懂啊!直到后来看到api我说的那一坨,哦吼,每个都有对应的解释啊。

具体我就不多说了,英文也不难,大家一看就懂了

parse进阶

输入:url.parse(‘http://www.flowerfat.com‘, true)

第二个参数的目的:解析query时,是否用QueryString这个module。

这个设置为true的时候,解析到的query就成了键值对的形式。

输入:url.parse(‘//www.flowerfat.com’, true)

出问题了,host都得不到

输入:url.parse(‘//www.flowerfat.com’, true, true)

结果正确了,第三个参数默认是false,这里设置成true ,就能正确解析了。

这里我没懂,scott哥也没说这个参数是干啥的。不过我们来看api中:slashesDenoteHost是第三个参数的名字,百度了下,网上的说法是它会去认//与/,这两个中间的当作host。

具体我也不造理解的对不,又懂得朋友可以批评指教。

format

作用:与parse相反,即把上面解析输出的结果丢到这个函数里,返回url输入

输入:url.format( {protocol: ‘http:’,……,path: ‘/’,href: ‘http://www.flowerfat.com/’ } );

输出:’http://www.flowerfat.com

resolve

作用:我理解是拼接,有一定规则的拼接

详情正如api里的Example:

url.resolve('/one/two/three', 'four')         // '/one/two/four'
url.resolve('http://example.com/', '/one')    // 'http://example.com/one'
url.resolve('http://example.com/one', '/two') // 'http://example.com/two'


Query Strings

懂的人都知道,我们用get方法跟服务器交流的时候,’?’后面的请求参数很重要。那么这个问号后面的请求参数就是我们parse后的query的值

对应api地址:https://nodejs.org/api/querystring.html

对应慕课网视频地址:http://www.imooc.com/video/6711

stringify

序列化:把键值对变成网址的形式

parse ###

反序列化:相当于前面我们提到的url.parse方法中的第二个参数,这是为true

escape、unescape

转义和反转义

HTTP源码

这可是个大工程,视频里在这部分说了一堆,我表示我睡着了。。。

中间部分都是一些需要了解的概念和知识,这些有助于我们后面关于HTTP源码的了解,这里就不赘述了。

对应api地址:https://nodejs.org/api/http.html

对应慕课网视频地址:http://www.imooc.com/video/7963

直接来看源码部分(源码来自Github!but!我在github上找不到视频里的那个工程啊,什么鬼,于是就选了个下面的这个,朋友们海涵)

nodejs对应源码地址:https://github.com/nodejs/node

然后在github页面按下t, 就是工程的搜索功能!卧槽,这个有点厉害 然后搜索http.js,就是我们要的HTTP的源码了哈

var http = require('http')

http
.createServer(function(req, res) {
res.writeHead(200, {'Content-Type':'text/plain'})
res.write('Hello Ming')
res.end()
})
.listen(2015)


我表示这段真没啥好说的。视频里针对上面代码的由来,追踪了下github上的源码。十几分钟的视频下来我是懵圈了,根本不明所以。朋友们你们加油,不说了,都是泪。

HTTP 爬虫

作为一个干活分享者,显然上面的乱七八糟的不是我的风格,这里继续copy视频里的好东西。

对应视频地址:http://www.imooc.com/video/7965



目的

所谓爬数据,我理解就是把我们需要的东西get到。(其实爬网页对html也要有一定了解)

执行1

为了方便爬,我们按照作者的意思,安装一个插件 :npm install cheerio ,目的是快速找到我们要爬的数据

在网页上审查元素,找到我们想要的:

// <div class="mod-chapters">
//   <div class="chapter chapter-active">...</div> 后面的active表示这个item是否展开
//   <div class="chapter chapter-active">...</div>
//   <div class="chapter">...</div>
//   <div class="chapter">...</div>
//   <div class="chapter">...</div>
// </div>


主要代码(不要问我res.on(‘data’, function(data)里的data是哪儿来的,下篇文章见):

var http = require('http')
var cheerio = require('cheerio')
var url = 'http://www.imooc.com/learn/348'

// 相当于main 我们在这里解析html
function filterChapters(html){
var $ = cheerio.load(html)
// 这个跟视频里的learnchapter不同,可能是慕课网改了吧
// 通过这个方法就拿到了类名
var chapters = $('.chapter')
// 打印数组的长度
console.log('打印 '+chapters.length)
}

http.get(url, function (res) {
var html = ''

res.on('data', function(data) {
html += data
})

res.on('end', function(){
filterChapters(html)
})
}).on('error', function() {
console.log('获取网站数据出错!')
})


我们引入了cheerio,并用它来更好的get对应的数据

这里我们看,跟之前的代码比较,就多了个函数:filterChapters

在接收完毕网页后,把网页数据传到这个函数里,进行整理。

在cdm中执行上面的代码:

node crawierPlus.js


打印结果如下:

打印 5


执行2

显然一个数组长度不是我们想要的,继续,嘿咻嘿咻!

由执行1看到,chapters这个“数组”就是我们要的内容了。我们继续解析,如何拿到标题呢?

看网页的相关审查元素:



chapters.each(function(item){
var chapter = $(this)
var chapterTitle = chapter.find('strong').text()
console.log(chapterTitle + '\n')
})


通过each方法,得到每个chapter。通过find的方法,得到strong,在.text()得到strong里的text

再来看对应video的获取:



从图上能看出,video下有两个对应的条目

chapters.each(function(item){
var chapter = $(this)
var chapterTitle = chapter.find('strong').text()
console.log(chapterTitle + '\n')
var videos = chapter.find('.video').children('li')

videos.each(function(item){
var video = $(this).find('.studyvideo')
var videoTitle = video.text()
var id = video.attr('href').split('video/')[1]
console.log('【'+id+'】  '+videoTitle)
})
})


对比上面的find方法,我们发现’strong’和’.video’有个不同点,’.video’前面有个’.’,大胆假设,因为video是一个class,而strong不是。故而有此区别

跑一遍上面的code,我们就能看到一个很好看的结果了。

我们是打log,而视频里作者是把数据都封装到了一起,用的是push的方法,具体我也不懂,就不瞎bb了。

Code

var http = require('http')
var cheerio = require('cheerio')
var url = 'http://www.imooc.com/learn/348'

function filterChapters(html){
var $ = cheerio.load(html)
var chapters = $('.chapter')

var courseData = []

chapters.each(function(item){
var chapter = $(this)
var chapterTitle = chapter.find('strong').text()
var videos = chapter.find('.video').children('li')

var chapterData = {
chapterTitle: chapterTitle,
videos:[]
}

videos.each(function(item){
var video = $(this).find('.studyvideo')
var videoTitle = video.text()
var id = video.attr('href').split('video/')[1]

chapterData.videos.push({
title:videoTitle,
id: id
})
})

courseData.push(chapterData)
})

return courseData
}

function printCourseInfo(courseData){
courseData.forEach(function(item){
var chapterTitle = item.chapterTitle
console.log(chapterTitle + '\n')
item.videos.forEach(function(video){
console.log(' 【'+video.id+'】 '+ video.title + '\n')
})
})
}

http.get(url, function (res) {
var html = ''

res.on('data', function(data) {
html += data
})

res.on('end', function(){
var courseData = filterChapters(html)
printCourseInfo(courseData)
})
}).on('error', function() {
console.log('获取网站数据出错!')
})


个人博客

欢迎来访我的干货个人博客:http://www.flowerfat.com
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: