美文网首页
nodejs bing 美图爬虫

nodejs bing 美图爬虫

作者: yuzhiyi_宇 | 来源:发表于2019-07-28 15:31 被阅读0次

    之前一直想学习一下爬虫,但是苦于一直没时间学习 python,后来查资料的时候看到 nodejs 也是可以做爬虫,就决定用 nodejs 做一个爬取 bing 上的美图并设置成桌面壁纸,并且每隔一顿时间更新壁纸。

    nodejs 做爬虫优劣

    其中一个优点是其语言是 JavaScript,JavaScript 一开始就是运行在浏览器上的脚本语言,优势就是对网页上的 dom 元素操作,而不需要像 python 要通过正则。

    另一个优点是其单线程异步的,通过事件循环来处理任务。nodejs 适合爬虫这种 IO 密集操作。

    其劣势在对于爬到的数据的处理,如果需要做大量复杂操作,nodejs 可能就会有点力不从心,对于 CPU 密集的操作就没有其他支持多线程的语言来的好。

    当然对于我们这种不需要太多复杂数据操作的来说 nodejs 足够了。

    依赖库

    request

    建立其对目标接口请求或者网页的链接,并返回相应的数据。
    

    fs

    对本地文件进行操作。
    

    node-schedule

    设置定时执行任务。
    

    child_process

    nodejs 内置库,可以用来执行 shell 命令。
    

    爬虫实现

    实现分为以下三部分:

    • 请求 bing 图片并保存至本地
    • 获取每日最新 bing 图片并删除旧的图片
    • 读取本地图片定时设置桌面壁纸

    请求 bing 图片并保存至本地

    function requestBingImage({index = 0, perpage = 10}) {
        request.get(`http://cn.bing.com/HPImageArchive.aspx?format=js&idx=${index}&n=${perpage}&mkt=zh-CN`, async function (error, response, body) {
            if (error) {
                return;
            }
            const data = JSON.parse(body);
            const images = data.images;
            if (!images || images.length === 0) {
            } else {
                const isExistFile = fs.existsSync(filePath);
                if (!isExistFile) {
                    fs.mkdirSync(filePath);
                }
                let url, image, fileName, imagePath, isExistImage, absolutePath, isFirstImage = true;
                for (let i = 0, length = images.length; i < length; i++) {
                    image = images[i];
                    url = bing_url + image.url;
                    fileName = image.enddate + '.jpg';
                    imagePath = path.join(filePath, fileName);
                    isExistImage = fs.existsSync(imagePath);
                    if (!isExistImage) {
                        try {
                            await utils.saveFile(imagePath, url);
                            absolutePath = __dirname + '/' + path.join(filePath, fileName);
                            if (isFirstImage) {
                                setDesktopBackground(absolutePath);
                                isFirstImage = false;
                            }
                        } catch (e) {
                            console.log(e);
                        }
                    } else {
                        return;
                    }
                }
            }
        });
    }
    
    function initRequestBingImage() { // 获取bing图片
        const isExistFile = fs.existsSync(filePath);
        if (!isExistFile) {
            fs.mkdirSync(filePath);
        }
        const files = fs.readdirSync(filePath);
        if (files && files.length === 0) {
            requestBingImage({index: 0, perpage: 10});
        }
    }
    

    获取每日最新bing图片并删除旧的图片

    function initRequestDailyBingImageSchedule() { // 获取每日最新bing图片并删除旧的图片
        requestDailyBingImage();
        removeOverDaysImage();
        schedule.setSchedule(config.DAILYSENDDATE, () => {
            requestDailyBingImage();
            removeOverDaysImage();
        });
    }
    
    function requestDailyBingImage() {
        if (!isExistTodayImage()) {
            requestBingImage({index: 0, perpage: 10});
        }
    }
    
    function isExistTodayImage() {
        const nowDay = moment();
        const nowDayFormat = nowDay.format('YYYYMMDD');
        const fileName = nowDayFormat + '.jpg';
        const imagePath = path.join(filePath, fileName);
        const isExistTodayImage = fs.existsSync(imagePath);
        return isExistTodayImage;
    }
    
    function removeOverDaysImage() {
        const nowDay = moment();
        const bingImages = fs.readdirSync(filePath);
        let overDays;
        for (let row of bingImages) {
            overDays = Math.abs(moment(row.split('.')[0]).diff(nowDay, 'days'));
            if (overDays > config.OVERDAYS) {
                fs.unlink(path.join(filePath, row), () => {
                    console.log('删除旧图片成功!');
                });
            }
        }
    }
    

    读取本地图片定时设置桌面壁纸

    function initSetDesktopSchedule() { // 定时设置桌面壁纸
        if (isExistTodayImage()) {
            setDesktopBackground();
        }
        schedule.setSchedule(config.SENDDATE, () => {
            setDesktopBackground();
        });
    }
    
    function setDesktopBackground() {
        const bingImages = fs.readdirSync(filePath);
        let isSetUp, absolutePath, isAllSetUp = true, imagePath, isExistImage;
        let length = bingImages.length, bingImage;
        for (let i =  length - 1; i >= 0; i--) {
            bingImage = bingImages[i];
            isSetUp = bingSetUpImages.includes(bingImage);
            if (!isSetUp) {
                imagePath = path.join(filePath, bingImage);
                isExistImage = fs.existsSync(imagePath);
                if (isExistImage) {
                    bingSetUpImages.push(bingImage);
                    absolutePath = __dirname + '/' + path.join(filePath, bingImage);
                    setDesktopBackgroundCmd(absolutePath);
                    isAllSetUp = false;
                    break;
                }
            }
        }
        if (isAllSetUp) {
            bingSetUpImages = [];
        }
    }
    
    async function setDesktopBackgroundCmd(absolutePath) {
        try {
            const cmd = `gsettings set org.gnome.desktop.background picture-uri 'file://${absolutePath}'`;
            await utils.execCmd(cmd);
            console.log('设置壁纸成功!');
        } catch (e) {
            console.log(e);
            console.log('设置壁纸失败!');
        }
    }
    

    详细代码

    详细代码请参考 BingWallpaper

    相关文章

      网友评论

          本文标题:nodejs bing 美图爬虫

          本文链接:https://www.haomeiwen.com/subject/femkrctx.html