一、Node.js基礎知識
1、概念
- 簡單的說 Node.js 就是運行在服務端的 JavaScript。
- Node.js 是JavaScript的運行環境
- Node.js 使用了一個事件驅動、非阻塞式 I/O 的模型,使其輕量又高效。
2、安裝使用
官網下載地址:http://nodejs.cn/
nodeJS5個基本對象:
- 1、require 引入模塊
- 2、export 導出對象
- 語法:
- export.屬性 = 值;
- export.方法名 = 函數;
- 注意:
- export時module對象的引用 export == module.export (指向同一個內存空間)
- export是module.export的引用, 不能改指向,只能添加屬性和方法
- module.export才是真正的暴露對象,指向哪里就暴露哪里-----推薦使用
- 語法:
- 3、module 模塊對象
- module.export
- module.export.屬性 = 值
- module.export.方法名 = 函數
- module.export = 對象或函數
- module.id 模塊id,模塊名稱
- module.parent 模塊父級
- module.filename 模塊文件名和路徑
- module.children 子模塊列表
- module.paths 模塊查找路徑,如果當前目錄找不到
- node_modules就去上一級目錄找,直到根目錄
- module.export
- 4、__filename 當前js文件的絕對路徑
- 5、__dirname 當前js文件所在文件夾絕對路徑
npm包管理器(node Package Manager)
- package.json是node.js的項目描述文件,以json格式的形式描述項目
- 創建package.json文件 ----> npm init ------ npm init -y ---->自動全部yes創建
- package.json常用屬性
- name: 項目名稱
- version:版本號
- description:項目描述
- main:主模塊
- dependencies:項目依賴
- devDependencies :開發時依賴
- scripts:腳本命令,可以使用npm命令執行
- license:開源協議
- npm常用指令:
- npm install <包的名稱> i--->install
- npm i <包的名稱>@版本號 //安裝指定版本
- npm i <包的名稱> -g全局安裝 -S(save)寫入項目依賴列表 -D(dev)寫入開發依賴列表
- npm search <包的名稱> //搜索包
- npm view <包的名稱> //查看包
- npm uninstall <包的名稱> //卸載包
- npm update <包的名稱> //更新包
cnpm (淘寶鏡像)
- npm install -g cnpm --registry=https://registry.npm.taobao.org
nodeJS回調函數
- 回調函數機制:
- a.定義一個普通函數
- b.將函數作為參數傳入另一個函數(調用者)
- c.調用者在執行過程中根據時機和條件決定是否調用函數
- 回調函數用途:
- 通常用於在達到某個時機或條件時,需要執行代碼的情況,使用回調函數
同步和異步
-
同步:上一行執行完成后,下一行才能得到執行
-
異步:將比較復雜的任務以任務線程實現,不用等上一句執行完成,下一句也能執行。
-
異步的三種實現方式:
- (1) 回調函數
回調函數不一定是異步(forEacch),異步一定有回調函數 - (2) 事件 (針對服務器端的事件)
事件源.on('事件名稱',回調函數)
/* 開啟一個服務器*/ var http = require('http'); // 建立服務器 var app = http.createServer(function(request, response) { response.writeHead(200, { "Content-Type": "text/plain" }); response.end("Hello world!"); }); //啟動服務器 app.listen(80,function(){ console.log('服務器已運行') })
- (3) promise 承諾對象
/* 什么是promise? promise是es6中新增的承諾對象,用於對異步的操作進行消息的傳遞 promise的狀態? Pending 等待中 Resolved 成功 Rejected 失敗 Pending => Resolved Pending => Rejected promise 有什么用? promise可以傳遞異步消息 由於異步的返回結果時間順序不可控,所以需要使用promise來統一控制輸出結果 */ var promise = new Promise(function(resove,reject){ resolve() }) //調用對象 promise.then(res>{ //成功的回調 }).catch(err=>{ //失敗的回調 }) //利用promise對象的all方法可以實現手動調整輸出順序,相當於把異步變為同步 Promise.all([p1,p2]).then(datas=>{ //返回數組 })
- (1) 回調函數
二、Buffer緩存區和文件模塊
1、Buffer緩存區
概念
在內存中開辟了一個臨時區域,用於存放我們需要運算的字節碼
創建緩存區
- 創建指定長度的緩存區
var buf = new Buffer(大小) //創建5個字節的緩存區
buf.write('a') //存入一個字節 轉成16進制 的Ascall碼的61 在node中默認使用utf-8編碼,一個中文3個字節
- 按指定的數組編碼創建緩存區
var buf = new Buffer([十進制編碼]) //數字小可以
- 按指定字符創建緩存區
var buf = new Buffer('字符串')
寫入緩存區
buf.write('字符串')
讀緩存區
buf.toString()
復制緩存區
buf.copy(buf2)
2、文件模塊(fs)
讀取文件
- 由於nodejs是服務端程序,必須要有文件讀寫操作,在客戶端沒有這樣的功能
- 文件讀寫有兩種方式:
- 直接讀取:
- 將硬盤上的所有內容全部讀入內存以后才觸發回調函數
- 兩種寫法:
//異步:定義一個回調函數,接收讀取到的內容 fs.readFile('文件路徑',(err,data)=>{}) //同步:幾乎所有fs的函數都有同步版本,只需在異步版本后面加Sync即可 (Async:異步) fs.readFileSync('文件路徑')
- 流式讀取:
- 將數據從硬盤中讀取一節就觸發回調函數,實現大文件操作
- 直接讀取:
寫文件
同步版本:
fs.writeFileSync('文件名','數據')
異步版本:
fs.writeFile('文件名','數據',funciton(err){/*寫完文件以后執行的代碼*/})
讀取文件信息
fs.stat('文件名',function(err,state){
//state時文件信息對象,包含了常用的文件信息
//size: 文件大小,單位字節
//mtime: 文件修改時間
//birthtime 文件創建時間
//方法
.isFile() //判斷當前查看的對象是不是一個文件
.isDirectory() //判斷是不是一個目錄
})
刪除文件
fs.unlink('文件名',function(err){})
需求:填寫代碼實現刪除一個非空目錄
- 刪除空目錄
fs.rmdir()
- 讀取目錄中的文件及文件夾列表
fs.readdir()
- 讀取每一個文件夾的詳細信息
fs.stat()
- 判斷如果是文件
fs.unlink()
- 判斷如果是目錄
//遞歸調用自己
- 刪除空目錄
fs.rmdir()
- 演示代碼
var fs = require('fs');
var path = require('path');
function rmdir(p){
//獲取文件列表
var list = fs.readdirSync(p);
list.forEach((item)=>{
//拼接路徑
let p1 = path.join(p,item);
//判斷是否為文件
if(fs.statSync(p1).isFile()){
fs.unlinkSync(p1);
}else{
//遞歸調用自己
arguments.callee(p1);
}
})
//刪除空文件夾
fs.rmdirSync(p);
}
rmdir('./data1');
流式讀取
- 流:什么是流
- 所有互聯網的數據都是以流的方式,流式一組有起點有終點的數據傳輸方式
- 流的操作:
- 流式讀取文件
//可讀取數據的流 var fs = require("fs"); var data = ''; // 創建可讀流 var readerStream = fs.createReadStream('input.txt'); // 設置編碼為 utf8。 readerStream.setEncoding('UTF8'); // 處理流事件 --> data, end, and error readerStream.on('data', function(chunk) { data += chunk; }); readerStream.on('end',function(){ console.log(data); }); readerStream.on('error', function(err){ console.log(err.stack); }); console.log("程序執行完畢");
- 以流的方式寫文件
//可寫入數據的流 var fs = require("fs"); var data = 'hello world'; // 創建一個可以寫入的流,寫入到文件 output.txt 中 var writerStream = fs.createWriteStream('output.txt'); // 使用 utf8 編碼寫入數據 writerStream.write(data,'UTF8'); // 標記文件末尾 writerStream.end(); // 處理流事件 --> data, end, and error writerStream.on('finish', function() { console.log("寫入完成。"); }); writerStream.on('error', function(err){ console.log(err.stack); }); console.log("程序執行完畢");
- 管道流
管道提供了一個輸出流到輸入流的機制。通常我們用於從一個流中獲取數據並將數據傳遞到另外一個流中
var fs = require("fs"); // 創建一個可讀流 var readerStream = fs.createReadStream('input.txt'); // 創建一個可寫流 var writerStream = fs.createWriteStream('output.txt'); // 管道讀寫操作 // 讀取 input.txt 文件內容,並將內容寫入到 output.txt 文件中 readerStream.pipe(writerStream); console.log("程序執行完畢");
- 鏈式流
//壓縮文件 var fs = require('fs'); var zlib = require('zlib'); // 壓縮 input.txt 文件為 input.txt.gz fs.createReadStream('input.txt') .pipe(zlib.createGzip()) .pipe(fs.createWriteStream('input.txt.gz')) console.log("文件壓縮完成。"); //解壓文件 var fs = require("fs"); var zlib = require('zlib'); // 解壓 input.txt.gz 文件為 input.txt fs.createReadStream('input.txt.gz') .pipe(zlib.createGunzip()) .pipe(fs.createWriteStream('input.txt')); console.log("文件解壓完成。");
三、常用模塊與網絡爬蟲
1、常用模塊
path模塊
- 格式化路徑
path.nomalize(p)
- 拼接路徑(將多個字符串拼接成一個完整路徑)
/*使用path.jon拼接文件路徑和 連接符 拼接優點
1.自動幫我們添加路徑分隔符(根據當前操作系統)
2.自動改正錯誤的路徑分隔符
*/
path.join(path1,path2)
let url = path.join(__dirname,path1); //常用
- 返回路徑中文件夾部分
path.dirname(p)
- 返回路徑中文件部分(文件名和擴展名)
path.basename(p)
- 返回路徑中文件的后綴名
path.extname(p)
- 返回路徑字符串的對象。
path.parse(path)
- 從對象中返回路徑字符串,和parse相反
path.format(path)
url模塊
- 什么是url?
- url是全球統一資源定位符,對網站資源的一種簡潔表達式,簡稱網址
- url的構成
- 完整
協議://用戶名:密碼@主機名.名.域:端口號/目錄名/文件名.擴展名?參數名=參數值&參數名2=參數值2#hash - 常見
協議://主機名.名.域/目錄名/文件名.擴展名?參數名=參數值&參數名2=參數值2#hash
- 完整
- node.js的url模塊
- 在node.js中提供了兩套給予url進行處理的API功能
- url模塊 和 (WHATWG URL標准模塊)
http模塊
- http協議
- 軟件開發模式
- 單機模式
- C/S模式 (Client / Server)
- B/S模式 (Brower / Server)
- http模塊
- get方法(用於模仿客戶端從服務器獲取數據)
var http = require('http'); http.get('url',function(res){ //res 是返回對象,接收到服務器響應的所有內容 res.on("data",function(a){ a //以流的方式獲取數據 //每節64kb }) })
2、網絡爬蟲
概念
是一種自動獲取網頁內容的程序
實現思路
-
打開網頁內容,查看源代碼,分析需要獲取的內容規律
-
編寫代碼,打開網頁,獲取html源代碼
-
通過正則表達式提出所需要的內容
-
遍歷數據,批量獲取所需要的內容