使用nodejs 搭建一个简单的api框架

Daming 2019-12-09
0条评论 432 次浏览
Daming 2019-12-090条评论 432 次浏览

最近学习了一点点nodejs,使用nodejs 制作了一个带 路由的 简易框架, 实现爬取微博热搜、爬取百度新闻 并提供api 等功能。

项目地址:https://github.com/crazyming9528/simpleNodeJsAPI

每一个js是一个模块,模块暴露一个函数,接收request 和respond 两个参数,输出经过AjaxReturn 包装后的 json数据。
爬取微博热搜模块:

https://github.com/crazyming9528/simpleNodeJsAPI/blob/master/modules/news/weibo.js

const superagent = require('superagent');
const cheerio = require('cheerio');
const AjaxReturn = require('../../utils/AjaxReturn');



    let getNews = (res) => {
        let newsArr = [];
        // 访问成功,请求http://news.baidu.com/页面所返回的数据会包含在res.text中。

        /* 使用cheerio模块的cherrio.load()方法,将HTMLdocument作为参数传入函数
           以后就可以使用类似jQuery的$(selectior)的方式来获取页面元素
         */
        let $ = cheerio.load(res.text);

        // 找到目标数据所在的页面元素,获取数据
        $('div#pl_top_realtimehot table tbody tr a').each((idx, ele) => {
            // cherrio中$('selector').each()用来遍历所有匹配到的DOM元素
            // 参数idx是当前遍历的元素的索引,ele就是当前便利的DOM元素
            let news = {
                title: $(ele).text(),        // 获取标题
                href: "https://s.weibo.com"+$(ele).attr('href') // 获取链接
            };
            newsArr.push(news)              // 存入最终结果数组
        });
        return newsArr
    };



module.exports = function (request, response) {


    superagent.get('https://s.weibo.com/top/summary?cate=realtimehot')
        .end((err, res) => {

            let data = [];
            if (err) {
                AjaxReturn.json(response, null, AjaxReturn.ERROR_RESPONSE, '新闻获取失败');
                console.log(err);
                // console.log('新闻抓取失败');

            } else {

                data = getNews(res);


                // console.log(news);
            }

            AjaxReturn.json(response, data);
        })


};

配置路由

https://github.com/crazyming9528/simpleNodeJsAPI/blob/master/router.js

定义映射表routes,当请求的 path与 路由表中的路由对象path匹配一致时,即调用对应的函数,例如:请求xxx.com/weibo_hot 即可调用 上方的微博热搜模块

const url = require('url');
const path = require('path');
const fs = require('fs');
const AjaxReturn = require('./utils/AjaxReturn');
const news = require('./modules/news/news')
const home = require('./modules/sys/default')
const bd_news = require('./modules/news/baidu')
const weibo_hot = require('./modules/news/weibo')



exports.register = function (request, response,) {


    const routes = [
        {
            'url': '/',
            'handler': home,
        },
        {
            'url': '/news',
            'handler': news,
        },
        {
            'url': '/baidu_news',
            'handler': bd_news,
        },
        {
            'url': '/weibo_hot',
            'handler': weibo_hot,
        }
    ];


    var pathName = url.parse(request.url).pathname;

    // 执行相应请求路径的回调函数
    for (let i = 0, len = routes.length; i < len; i++) {
        if (routes[i].url === pathName) {
            routes[i].handler(request, response);
            return;
        }
    }


    // 请求路径为文件返回文件内容
    var file = path.resolve(__dirname, '.' + pathName);
    fs.exists(file, function (exists) {
        // 请求路径不存在返回404页面
        if (!exists) {
            AjaxReturn.json(response, [], AjaxReturn.ERROR_RESPONSE_PATH, '')
            // writeErrorPage(404, response, 'NOT_FOUND');
        } else {
            var stat = fs.statSync(file);
            // 请求路径为目录返回403页面
            if (stat.isDirectory()) {
                AjaxReturn.json(response, null, AjaxReturn.ERROR_RESPONSE_REQUEST_BAN)
                // writeErrorPage(403, response, 'FORBIDDEN');
            } else {

                //这里暂时还没想好怎么处理
                AjaxReturn.json(response, null, AjaxReturn.ERROR_RESPONSE);
                // response.writeHeader(200, {
                //     "Content-Type": "text/html"
                // });
                // response.end(
                //     fs.readFileSync(file, 'utf-8')
                // );
            }
        }
    });


}

创建服务

使用http模块的createServer创建
https://github.com/crazyming9528/simpleNodeJsAPI/blob/master/index.js

const server = http.createServer(function (req, response) {
    // 注册路径和其对应回调函数
    router.register(req, response);
});


server.listen(port, host, function () {
    console.log(`${appName} 运行在http://${host}:${port}`);
});
1+

发表评论

电子邮件地址不会被公开。