nodejs bing 美图爬虫

2019-07-28  本文已影响0人  yuzhiyi_宇

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

nodejs 做爬虫优劣

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

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

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

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

依赖库

request

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

fs

对本地文件进行操作。

node-schedule

设置定时执行任务。

child_process

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

爬虫实现

实现分为以下三部分:

请求 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

上一篇下一篇

猜你喜欢

热点阅读