之前一直想學(xué)習(xí)一下爬蟲,但是苦于一直沒時間學(xué)習(xí) python,后來查資料的時候看到 nodejs 也是可以做爬蟲,就決定用 nodejs 做一個爬取 bing 上的美圖并設(shè)置成桌面壁紙,并且每隔一頓時間更新壁紙。
nodejs 做爬蟲優(yōu)劣
其中一個優(yōu)點是其語言是 JavaScript,JavaScript 一開始就是運行在瀏覽器上的腳本語言,優(yōu)勢就是對網(wǎng)頁上的 dom 元素操作,而不需要像 python 要通過正則。
另一個優(yōu)點是其單線程異步的,通過事件循環(huán)來處理任務(wù)。nodejs 適合爬蟲這種 IO 密集操作。
其劣勢在對于爬到的數(shù)據(jù)的處理,如果需要做大量復(fù)雜操作,nodejs 可能就會有點力不從心,對于 CPU 密集的操作就沒有其他支持多線程的語言來的好。
當(dāng)然對于我們這種不需要太多復(fù)雜數(shù)據(jù)操作的來說 nodejs 足夠了。
依賴庫
request
建立其對目標(biāo)接口請求或者網(wǎng)頁的鏈接,并返回相應(yīng)的數(shù)據(jù)。
fs
對本地文件進(jìn)行操作。
node-schedule
設(shè)置定時執(zhí)行任務(wù)。
child_process
nodejs 內(nèi)置庫,可以用來執(zhí)行 shell 命令。
爬蟲實現(xiàn)
實現(xiàn)分為以下三部分:
- 請求 bing 圖片并保存至本地
- 獲取每日最新 bing 圖片并刪除舊的圖片
- 讀取本地圖片定時設(shè)置桌面壁紙
請求 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('刪除舊圖片成功!');
});
}
}
}
讀取本地圖片定時設(shè)置桌面壁紙
function initSetDesktopSchedule() { // 定時設(shè)置桌面壁紙
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('設(shè)置壁紙成功!');
} catch (e) {
console.log(e);
console.log('設(shè)置壁紙失??!');
}
}
詳細(xì)代碼
詳細(xì)代碼請參考 BingWallpaper