资讯专栏INFORMATION COLUMN

【小工具】node.js下载json对象中包含的所有图片链接

notebin / 1293人阅读

摘要:我先是在浏览器上输入豆瓣的地址,拉下来数据。根据豆瓣的图片地址,建立了对应的文件夹以下逻辑代码中该函数的功能是接收一个数组数据的文件路径,就可以将该中包含的所有的图片路径全部下载到中下对应的文件夹中。

今天在看微信小程序,数据是从网上找的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;
数据准备完成。就可以在浏览器中访问本地数据库保存的数据了。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/83428.html

相关文章

  • 一个时快速搭建微信程序

    摘要:第一步搭开发环境首先,我们需要在本地搭建好微信小程序的开发环境。在微信小程序中,所有的网络请求受到严格限制,不满足条件的域名和协议无法请求。第五步配置微信小程序云端示例镜像中,已经部署好了,但是还需要在下修改配置中的域名证书私钥。 「小程序」这个划时代的产品发布快一周了,互联网技术人都在摩拳擦掌,跃跃欲试。可是小程序目前还在内测,首批只发放了 200 个内测资格(泪流满面)。本以为没有...

    izhuhaodev 评论0 收藏0
  • 分分钟教你用node.js写个爬虫

    摘要:爬虫介绍二爬虫的分类通用网络爬虫全网爬虫爬行对象从一些种子扩充到整个,主要为门户站点搜索引擎和大型服务提供商采集数据。 分分钟教你用node.js写个爬虫 写在前面 十分感谢大家的点赞和关注。其实,这是我第一次在segmentfault上写文章。因为我也是前段时间偶然之间才开始了解和学习爬虫,而且学习node的时间也不是很长。虽然用node做过一些后端的项目,但其实在node和爬虫方面...

    fanux 评论0 收藏0
  • 前端每周清单第 44 期: 2017 JS 调查报告、REST 接口实时化、ESM 的过去与未来

    摘要:巅峰人生年老兵思路上的转变,远比单纯提升技术更有价值本文节选自赵成教授在极客时间开设的赵成的运维体系管理课,是其对自己十年技术生涯的回顾与总结。赵成教授来自美丽联合集团,集团旗下两大主力产品是蘑菇街和美丽说,目前负责管理集团的技术服务团队。 showImg(https://segmentfault.com/img/remote/1460000012476504?w=1240&h=826...

    MASAILA 评论0 收藏0
  • Node.js微信公众号开发

    摘要:在微信开发者工具中调试和一定要正确域名一定是备案的绑定域名需要的放在服务器上的位置一定要正确参考微信公众号开发文档 node微信公众号开发 概览 key value 项目名称 node微信公众号开发 项目描述 使用node编写接口,前后端分离获取签名数据 开发者 leinov 发布日期 2018-11-07 仓库 github地址 安装&使用 下载 gi...

    OnlyLing 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<