day03
-
querystring
- 功能:
- 核心方法
- parse 将String – > Object
var str = 'http://www.baidu.com:8080/001?a=1&b=2#hash=20' var obj = qs.parse( str,'?','&' )
- parse( str , arg1 , arg2)
str: 你要处理的字符
arg1: 分隔字符
arg2:
将 = 转化为 : , (这句话前提是 & 符号是提前被转化的)
- stringify 将Object -> String
- escape 将 中文字符 编码
- unescape 将中文字符解码
-
http
核心方法
get
request
小爬虫
爬虫?
使用数据请求一段内容,然后将这段内容做数据清洗,最后在通过后端服务器发送到前台页面- 数据请求, 获得数据
- 数据清洗 ( 工具 cheerio )
- 安装 cheerio
$ cnpm i cheerio -S
- 使用cheerio
- 发送给前台
反爬虫
-
events
-
fs
-
stream
-
Node.js原生路由
-
前端异步流程工具
传统:
回调函数
流行:- Promise
- Generator函数
- Async函数
- Node.js nextTick setImmidate
- 第三方 async.js 库
小爬虫运用
请求的网址: http://jx.1000phone.net/teacher.php/Class/ classDetail/param/rqiWlsefmajGmqJhXXWhl3ZiY2dn
*/
var http = require( 'http' )
var cheerio = require( 'cheerio' )
// http.get(url/options,callback)
const options = {
hostname: 'jx.1000phone.net',
port: 80,
path: '/teacher.php/Class/classDetail/param/ rqiWlsefmajGmqJhXXWhl3ZiY2dn',
method: 'get',
headers: {
'Accept': 'text/html,application/xhtml+xml,application/ xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/ signed-exchange;v=b3',
'Accept-Encoding': 'gzip, deflate',
'Accept-Language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en; q=0.7',
'Cache-Control': 'no-cache',
'Cookie': 'PHPSESSID=ST-46480-wNTDM48QXeWJfh--WJ-Oupg44Oo-izm5ejd5 j1npj2pjc7i3v4z',
'Host': 'jx.1000phone.net',
'Pragma': 'no-cache',
'Proxy-Connection': 'keep-alive',
'Referer': 'http://jx.1000phone.net/teacher.php/Class/ index',
'Upgrade-Insecure-Requests': '1',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/ 74.0.3729.131 Safari/537.36',
'Content-Type': 'application/x-www-form-urlencoded'
}
};
// 创建静态服务器
http.createServer( function ( request, response ) {
response.writeHead( 200 , {
'Content-type': 'text/html;charset=utf8'
})
var req = http.get( options,function( res ) {
res.setEncoding('utf8');
let rawData = '';
res.on('data', (chunk) => { rawData += chunk; });
res.on('end', () => {
try {
var $ = cheerio.load( rawData )
$('td.student a').each( function( index,ele ) {
response.write( `<h3>${$( this ).text().toString()} </h3>` )
})
response.end()
} catch (e) {
console.error(e.message);
}
})
}).on('error', (e) => { // get的报错
console.error(`problem with request: ${e.message}`);
})
req.end()
}).listen(8000,'localhost',function () {
console.log( `服务器运行在: http://localhost:8000` )
})
querystring 的4个核心方法的使用
/*
1. parse( str , arg1 , arg2)
str: 你要处理的字符
arg1: 分隔字符
arg2:
将 = 转化为 : , (这句话前提是 & 符号是提前被转化的)
*/
var qs = require( 'querystring' )
var url = require( 'url' )
var str = 'http://www.baidu.com:8080/001?a=1&b=2#hash=20'
var obj = qs.parse( str,'?','&' )
// console.log('====================================');
// console.log( obj );
// console.log('====================================');
/*
{
'http://www.baidu.com:8080/001?a': '1',
b: '2#hash=20'
}
*/
// stringify
// console.log( qs.stringify( obj ) )
// var str = 'http://www.baidu.com:8080/001?a=1&b=2#hash=20'
// http%3A%2F%2Fwww.baidu.com%3A8080%2F001=&a%3D1=b%3D2%23hash%3D20
// %3A : %2F / %3D = %23 # =& ?
// escape
var charaStr = 'http://www.baidu.com/001?city=北京'
var urlObj = url.parse( charaStr )
var query = urlObj.query // city = 北京
// console.log( qs.escape( query) ) //city%3D%E5%8C%97%E4%BA%AC
// unescape
console.log( qs.unescape( qs.escape( query) ))
事件的声明和触发
var Events = require('events')
class MyEvents extends Events {}
var myEvents = new MyEvents ()
// console.log( myEvents )
// 声明事件
myEvents.on('aa',function(){
console.log( 'hello Node.js' )
})
// 事件的触发
myEvents.emit('aa')
fs文件的增删改查
/*
fs是Node.js中文件系统
功能: 操作文件或是目录
文件:
增: writeFile(路径,内容 , 错误优先的回调)
删
改
查
目录
增
删
改
查
*/
var fs = require( 'fs' )
// 文件的操作
// 增(创建)
/* fs.writeFile('./dist/1.txt','hello yyb',function( error ) {
if( error ) throw error
}) */
// 改
/* fs.appendFile('./dist/1.txt','\nhello 千锋~~~','utf8',function( error ) {
if( error ) throw error
console.log('文件修改成功')
})
*/
// 查
// fs.readFile( './dist/1.txt','utf8',function( error, data ) {
// if ( error ) throw error
// // console.log( data.toString() ) // 二进制数据
// console.log( data )
// console.log('文件读成功了')
// })
// 删
// fs.unlink( './dist/1.txt', function( error ) {
// if( error ) throw error
// console.log( '文件删除成功' )
// })
fs 目录的增删改查
/*
fs是Node.js中文件系统
功能: 操作文件或是目录
文件:
增: writeFile(路径,内容 , 错误优先的回调)
删
改
查
目录
增
删
改
查
*/
var fs = require( 'fs' )
// 目录-增
/* fs.mkdir('./dist',function( error ) {
if( error ) throw error
console.log( '目录创建成功' )
}) */
// 目录-改
/* fs.rename('./dist','./fs_dist',function( error ) {
if( error ) throw error
console.log(' 目录名称修改成功 ')
}) */
// 目录-查
// for( var i = 0 ; i < 10 ; i ++ ){
// fs.writeFile(`./fs_dist/${i}.txt`,i,function( err ) {
// console.log( `第${i}个文件创建成功` )
// })
// }
// fs.readdir('./fs_dist','utf-8',function ( error,data ) {
// if( error ) throw error
// //console.log( data ) // 以文件名为元素构成的数组
// for ( var i = 0 ; i < data.length; i ++ ){
// fs.readFile( `./fs_dist/${data[i]}`,'utf8',function( error , content ) {
// if( error ) throw error
// console.log( content )
// })
// }
// })
// 目录-删
// fs.rmdir(path,callback) 这个方法只能删除空目录
// fs.rmdir( './fs_dist', function ( error ) {
// if( error ) throw error
// console.log('目录删除成功')
// })
// fs.readdir('./fs_dist','utf-8',function ( error,data ) {
// if( error ) throw error
// //console.log( data ) // 以文件名为元素构成的数组
// for ( var i = 0 ; i < data.length; i ++ ){
// fs.unlink( `./fs_dist/${data[i]}`,function( error ) {
// if( error ) throw error
// })
// }
// })
fs.rmdir('./fs_dist',function( error ) {
if( error ) throw error
})
stream 流 和 pipe 管道流
/*
stream 流: 减少内存消耗, 增加效率
可读的流
可写的流
举例: 压缩包的创建
名词:
pipe --> 管道流
*/
var fs = require( 'fs' )
var zlib = require('zlib') // 创建压缩包
var readeStream = fs.createReadStream( './dist/1.txt' )
var writeStream = fs.createWriteStream( './dist/1.txt.gz' )
var gzip = zlib.createGzip() // 空压缩包
readeStream
.pipe( gzip )
.pipe( writeStream )
Node.js 中的原生路由
/*
Node.js 中的原生路由
名词解释:
什么是路由?
*/
var http = require( 'http' )
var fs = require( 'fs' )
http.createServer( function ( req, res ) {
//console.log(req)
switch ( req.url ) {
case '/home':
res.write('home')
res.end()
break;
case '/mine':
res.write('mine')
res.end()
break;
case '/login':
fs.readFile( './static/login.html',function ( error , data ) {
if ( error ) throw error
res.write( data )
res.end()
})
break;
case '/fulian.jpg':
fs.readFile( './static/fulian.jpg','binary',function( error , data ) {
if( error ) throw error
res.write( data, 'binary' )
res.end()
})
break;
default:
break;
}
}).listen( 8000, 'localhost', function () {
console.log( '服务器运行在: http://localhost:8000' )
})
generator函数
/*
generator函数
概念, 在function 关键字后面写一个* ,表示一个generator函数
generator通过 yield 关键字来定义任务
*/
function* p1 () {
yield '任务1';
yield '任务2';
yield '任务3';
yield '任务4';
yield '任务5';
yield function* p2() {
yield '任务7'
}
return '任务6'
}
var p = p1()
console.log(p.next())
console.log(p.next())
console.log(p.next())
console.log(p.next())
console.log(p.next())
console.log(p.next())
console.log(p.next())
/*
{ value: '1', done: false }
{ value: '2', done: false }
{ value: '3', done: false }
{ value: undefined, done: false }
{ value: '5', done: false }
{ value: '6', done: false }
{ value: undefined, done: true }
{ value: undefined, done: true }
*/
/*
Promise
https://www.liaoxuefeng.com/wiki/1022910821149312/1023024413276544
*/
const p1 = new Promise ( function ( resolve, reject ) {
resolve( '任务一' )
})
.then ( function ( data ) {
console.log( data )
})
const p2 = new Promise ( function ( resolve, reject ) {
setTimeout( function () {
resolve( '任务二' )
},1000)
})
.then ( function ( data ) {
console.log( data )
})
console.log( '主线程任务 ')
// Promise
// .all([p1,p2]) // 先执行all中所有任务, 执行完成之后再去执行后面的任务
// .then( data => {
// console.log( '任务3' )
// })
Promise
.race([p1,p2]) // race 谁快输出谁
.then( data => {
console.log( '任务3' )
})