今天在看微信小程序,數據是從網上找的API請求下來的。就想能不能把數據保存到本地來,之後沒有網絡也能夠本身搭服務器提供數據。
說幹就幹,我打算用node來作。
我先是在瀏覽器上輸入豆瓣的API地址,拉下來json數據。,我去掉了不須要的頭尾,留下了中間的一個數組。由於我想保存數組中的電影信息。其它的並不須要。電影信息以下:
{
"rating": {
"max": 10,
"average": 9.6,
"stars": "50",
"min": 0
},
"genres": [
"犯罪",
"劇情"
],
"title": "肖申克的救贖",
"casts": [
{
"alt": "https://movie.douban.com/celebrity/1054521/",
"avatars": {
"small": "https://img3.doubanio.com/img/celebrity/small/17525.jpg",
"large": "https://img3.doubanio.com/img/celebrity/large/17525.jpg",
"medium": "https://img3.doubanio.com/img/celebrity/medium/17525.jpg"
},
"name": "蒂姆·羅賓斯",
"id": "1054521"
},
{
"alt": "https://movie.douban.com/celebrity/1054534/",
"avatars": {
"small": "https://img3.doubanio.com/img/celebrity/small/34642.jpg",
"large": "https://img3.doubanio.com/img/celebrity/large/34642.jpg",
"medium": "https://img3.doubanio.com/img/celebrity/medium/34642.jpg"
},
"name": "摩根·弗里曼",
"id": "1054534"
},
{
"alt": "https://movie.douban.com/celebrity/1041179/",
"avatars": {
"small": "https://img1.doubanio.com/img/celebrity/small/5837.jpg",
"large": "https://img1.doubanio.com/img/celebrity/large/5837.jpg",
"medium": "https://img1.doubanio.com/img/celebrity/medium/5837.jpg"
},
"name": "鮑勃·岡頓",
"id": "1041179"
}
],
"collect_count": 1072578,
"original_title": "The Shawshank Redemption",
"subtype": "movie",
"directors": [
{
"alt": "https://movie.douban.com/celebrity/1047973/",
"avatars": {
"small": "https://img3.doubanio.com/img/celebrity/small/230.jpg",
"large": "https://img3.doubanio.com/img/celebrity/large/230.jpg",
"medium": "https://img3.doubanio.com/img/celebrity/medium/230.jpg"
},
"name": "弗蘭克·德拉邦特",
"id": "1047973"
}
],
"year": "1994",
"images": {
"small": "https://img3.doubanio.com/view/movie_poster_cover/ipst/public/p480747492.webp",
"large": "https://img3.doubanio.com/view/movie_poster_cover/lpst/public/p480747492.webp",
"medium": "https://img3.doubanio.com/view/movie_poster_cover/spst/public/p480747492.webp"
},
"alt": "https://movie.douban.com/subject/1292052/",
"id": "1292052"
}
其中有不少圖片,我打算將他們所有下載到本地文件夾中。個人服務器結構以下:
app.js是服務器文件,處理不一樣路由的中間件都寫在route文件夾中。圖片就下載到public文件夾中的image下。根據豆瓣的圖片地址,創建了對應的文件夾:
如下js邏輯代碼中:
loadImageFromJson
該函數的功能是接收一個數組json數據的文件路徑,就能夠將該json中包含的全部的圖片路徑所有下載到public中images下對應的文件夾中。其中用到了一個異步下載第三方模塊:bagpipe
var fs = require("fs");
var http = require('http');
var url = require('url');
var path = require('path');
var Bagpipe = require('bagpipe');
var request = require('request');
var Files = [];
var Type = "";
//接收一個json文件,以及存放圖片的路徑
//解析出裏面的全部圖片的鏈接,
//並下載全部圖片到當前目錄下的image文件夾中
function loadFilesFromJson(jsonURL, destDir, fileType) {
//讀取文件中的全部的圖片連接
fs.readFile(jsonURL, "utf-8", function(err, doc) {
//將讀取到的普通字符串轉換爲json對象,
var jsonObj = JSON.parse(doc);
Type = fileType;
//迭代出對象中包含的url
itrator(jsonObj);
if (Files.length > 0) {
loadFilesFromNet(Files, destDir);
}
});
}
//遍歷json對象的全部屬性,找出全部的圖片連接
function itrator(obj) {
for (var item in obj) {
if (obj[item] instanceof Object) {
itrator(obj[item]);
} else {
if ((typeof obj[item]).toLowerCase() == "string" && obj[item].indexOf(Type) > -1) {
Files.push(obj[item]);
}
}
}
}
function loadFilesFromNet(Files, destDir) {
//設置併發的任務個數
var bagpipe = new Bagpipe(10);
//真正下載圖片文件的地方
var downloadFiles = function(src, dest, callback) {
request.head(src, function(err, res, body) {
if (src) {
request(src).pipe(fs.createWriteStream(dest)).on('close', function() {
//回調函數,打印出文件名
callback(null, dest);
});
}
});
};
//用for循環開啓每一次下載
for (var i = 0; i < Files.length; i++) {
try {
//根據url自動生成文件夾結構
createDirAccordingToUrl(Files[i], destDir);
//下載的文件的保存路徑
var destFile = path.resolve(destDir, Files[i].substr(Files[i].indexOf(".com/") + 5));
bagpipe.push(downloadFiles, Files[i], destFile, function(err, data) {
//打印的是下載成功的文件路徑
console.log(data);
});
} catch (e) {
console.log(e);
}
}
}
function createDirAccordingToUrl(originurl, dest) {
var urlobj = url.parse(originurl);
//將path用"/"分割爲數組
var dirs = urlobj.path.split('/');
var dir = dest;
for (var i = 0; i < dirs.length - 1; i++) {
dir += "/" + dirs[i];
console.log(dir);
//判斷是否存在,且是否爲文件夾
if (fs.existsSync(dir) && fs.statSync(dir).isDirectory()) {
//若是該層文件夾存在,就繼續判斷下一層
} else {
console.log("文件夾不存在,建立:" + dir);
fs.mkdirSync(dir);
}
}
}
exports.loadFilesFromJson = loadFilesFromJson;
//傳入源json文件,下載的文件存放的文件夾路徑,以及下載的文件類型
loadFilesFromJson("./zhihuhot.json", __dirname + "/public/zhihu", ".jpg");
用以上代碼就能夠下載圖片到本地了。可是這些數據還應該導入到數據庫。我使用的是mongodb數據庫,直接在命令行中輸入:
mongoimport -d 數據庫名 -c 集合名 文件名
便可將json文件中的對象都導入數據庫。十分方便。
這裏要注意一點:
導入的json文件中不能是剛纔用過的數組json文件,須要作簡單修改:先將數組的 []符號 刪掉,而後對象之間的逗號也要刪掉。最後就像這樣:
{} {} {} {}
導入數據以前,記得json文件中圖片的地址改爲本地的地址。
由於我是打算在本地搭建服務器使用,因此我將豆瓣的圖片地址域名所有改爲了這樣:
http://127.0.0.1:8080
個人服務器app.js文件以下:
var route = require("./route/route.js");
var express = require("express");
var app = express();
app.use(express.static('./public'));
//獲取電影詳情
app.get("/movie/detail/:movieid", route.detailRoute);
//獲取即將上映的電影
app.get("/movie/coming", route.comingRoute);
//獲取排行250電影
app.get("/movie/top250/:start/:count", route.top100);
app.listen(8080);
個人路由文件以下:
var MongoClient = require('mongodb').MongoClient;
//mongo服務器地址
var URL = 'mongodb://localhost:27017/farsight';
var detailRoute = function(req, res) {
console.log("detail");
//鏈接數據庫farsight,若是不存在,就建立它,並將其對象返回
MongoClient.connect(URL, function(err, db) {
if (err) {
console.error(err); //輸出錯誤信息
return;
} else {
//獲取集合對象
var collection = db.collection('moviedetail');
//查詢數據
collection.find({}).limit().skip().toArray(function(err, docs) {
if (err) throw err;
else {
console.log(docs);
if (docs.length == 0) {
res.send();
} else {
res.send(docs);
}
db.close();
}
});
}
});
}
var hotplaying = function(req, res) {
console.log("hotplaying");
//鏈接數據庫farsight,若是不存在,就建立它,並將其對象返回
MongoClient.connect(URL, function(err, db) {
if (err) {
console.error(err); //輸出錯誤信息
return;
} else {
//獲取集合對象
var collection = db.collection('hotplaying');
//查詢數據
collection.find({}).toArray(function(err, docs) {
if (err) throw err;
else {
console.log(docs);
if (docs.length == 0) {
res.send();
} else {
res.send(docs);
}
db.close();
}
});
}
});
}
//即將上映
var comingRoute = function(req, res) {
//鏈接數據庫farsight,若是不存在,就建立它,並將其對象返回
MongoClient.connect(URL, function(err, db) {
if (err) {
console.error(err); //輸出錯誤信息
return;
} else {
//獲取集合對象
var collection = db.collection('coming');
//查詢數據
collection.find({}).toArray(function(err, docs) {
if (err) throw err;
else {
if (docs.length == 0) {
res.send();
} else {
console.log("查到了" + docs.length);
// var jsonObj = JSON.parse(docs);
res.send(docs);
}
db.close();
}
});
}
});
}
//電影排行
var top100 = function(req, res) {
var count = req.params.count;
var start = req.params.start;
//鏈接數據庫farsight,若是不存在,就建立它,並將其對象返回
MongoClient.connect(URL, function(err, db) {
if (err) {
console.error(err); //輸出錯誤信息
return;
} else {
//獲取集合對象
var collection = db.collection('to100');
//查詢數據
collection.find({}).limit(count).skip(start).toArray(function(err, docs) {
if (err) throw err;
else {
console.log(docs);
if (docs.length == 0) {
res.send();
} else {
res.send(docs);
}
db.close();
}
});
}
});
}
exports.detailRoute = detailRoute;
exports.hotplaying = hotplaying;
exports.comingRoute = comingRoute;
exports.top100 = top100;
數據準備完成。就能夠在瀏覽器中訪問本地數據庫保存的數據了。